ときどきの雑記帖 RE* (新南口)
ノスタルジア
Zガンダム@テレ玉
「ジオンの亡霊」
- Gディフェンサー登場
- グワジン型の漂流戦艦
- ジャマイカン戦死
最後のジャマイカン戦死のくだり、
- ヤザンの乗るギャプランがドゴスギアのブリッジ前で静止
- ガンダム+Gディフェンサーがギャプランに向けて射撃
- ヤザン避ける
- ドゴスギアのブリッジ直撃
という流れなんだけど、 ニュータイプでもないのにジャストなタイミングで避けるヤザン… 野生の勘か🤔
次回「シャアの帰還」
sed
- sed: –posix now warns about nonportable backslashes in the ’s’ command - sed.git - GNU stream editor
- bug#78883: backslash interpretation in ’s’ replacement text violates POS
POSTD
2025年8月28日 2025年のReactとコミュニティの現状 | POSTD が流れてきて気がついたのだけど、 月イチくらいのペースで続いてたのね
POSTD | ニジボックスが運営するエンジニアに向けたキュレーションメディア
条件演算子
- C言語などでおなじみの三項の条件演算子(:?)、「Delphi 13」でObject Pascal言語に - やじうまの杜 - 窓の杜
- [B! software] C言語などでおなじみの三項の条件演算子(:?)、「Delphi 13」でObject Pascal言語に/Pascal言語の誕生から50年以上、ようやく導入【やじうまの杜】
// 従来の if 文
if Left < 100 then
X := 22
else
X := 45;
// if 演算子による代入
X := if Left < 100 then 22 else 45;
式の途中とか代入の右辺にifが現れると特別扱い(演算子扱い)するということなんだろうか
- RAD Studio 13 で導入予定の新機能:Delphi 言語の条件演算子(三項演算子)
- Coming in RAD Studio 13: A Conditional Ternary Operator for the Delphi Language
Delphi では、使い慣れた Pascal 指向の構文を可能な限り維持したいと考え、if 記号を演算子として使用することにしました。 つまり、if は、ソースコード内の位置に応じて、文または演算子を示すために使用できるようになりました。
ふむ
condition / conditional
で、イマサラな話ではあるんだけど、 conditional operator を条件演算子と訳したのは ちょいとよろしくないような気がする
strftime
Blueskyでこんな投稿を見かけた
strftime("%_4z", ..., &tm /* tm_gmtoff = 1800 */)
とかすると " + 30" とか出てくる ("+" の前にスペース 3 つ / 後にスペース 2 つ)
- precision は “+” までの文字数として効く (HHMMの部分には効かない)
- そして HHMM 全体が別途 4 桁の整数であるかのような振る舞いをする ("_" で space padding にすると HH が 0 なら leading zero が space に置き換わったような動作になる)
この挙動の互換性とか考えたくないなw (特に (2) のほう)
これが “%04z” だと “000+0030” になり “%4z” だと " +0043" になる。もうなにがなんだか
気になったのでちょっと調べてみた
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char outstr[200];
time_t t;
struct tm *tmp;
t = time(NULL);
tmp = localtime(&t);
if (tmp == NULL) {
perror("localtime");
exit(EXIT_FAILURE);
}
if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
fprintf(stderr, "strftime returned 0");
exit(EXIT_FAILURE);
}
printf("Result string is \"%s\"\n", outstr);
exit(EXIT_SUCCESS); }
こんなプログラムがあったのでそれを使っていくつか試してみる
kbk@toybox4:~$ ./a.out '%4z'
Result string is " +0900"
kbk@toybox4:~$ ./a.out '%04z'
Result string is "000+0900"
kbk@toybox4:~$ ./a.out '%_4z'
Result string is " + 900"
kbk@toybox4:~$ ./a.out '%a %_4z'
Result string is "Thu + 900"
kbk@toybox4:~$ ./a.out '%Y %_4z'
Result string is "2025 + 900"
kbk@toybox4:~$ ./a.out '%Y|%_4z'
Result string is "2025| + 900"
kbk@toybox4:~$ ./a.out '%Y|%_2z'
Result string is "2025| + 900"
kbk@toybox4:~$ ./a.out '%Y|%_1z'
Result string is "2025|+ 900"
kbk@toybox4:~$ ./a.out '%Y|%05z'
Result string is "2025|0000+00900"
kbk@toybox4:~$
“%4z” だと " +0043" になる
が再現されないけどそれはそれとして
strftime(3)の処理は glibc/time/strftime_l.c at master · bminor/glibc のこの関数が行っていて
static size_t
__strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,
const struct tm *tp, int yr_spec, bool *tzset_called
ut_argument_spec LOCALE_PARAM)
{
for (f = format; *f != '\0'; ++f)
{
/* Check for flags that can modify a format. */
(略)
/* As a GNU extension we allow to specify the field width. */
(略)
/* Check for modifiers. */
(略)
/* Now do the specified format. */
format_char = *f;
switch (format_char)
{
(略)
case L_('z'):
case L_('\0'): /* GNU extension: % at end of format. */
default:
/* Unknown format; output the format, including the '%',
since this is most likely the right thing to do if a
multibyte string has been misparsed. */
}
ところで書式指定文字を切り分けるswitch文で
ほかはすべてcase L_('b')
のようにL_がついているのにAだけ
case 'A':
なのはなぜ?🤔
z
それはさておき、zの処理を見ると
glibc/time/strftime_l.c at master · bminor/glibc
case L_('z'):
if (tp->tm_isdst < 0)
break;
{
int diff;
#if HAVE_TM_GMTOFF
diff = tp->tm_gmtoff;
#else
if (ut)
diff = 0;
else
{
struct tm gtm;
struct tm ltm;
time_t lt;
/* POSIX.1 requires that local time zone information is used as
though strftime called tzset. */
# if HAVE_TZSET
if (!*tzset_called)
{
tzset ();
*tzset_called = true;
}
# endif
ltm = *tp;
lt = mktime (<m);
if (lt == (time_t) -1)
{
/* mktime returns -1 for errors, but -1 is also a
valid time_t value. Check whether an error really
occurred. */
struct tm tm;
if (! __localtime_r (<, &tm)
|| ((ltm.tm_sec ^ tm.tm_sec)
| (ltm.tm_min ^ tm.tm_min)
| (ltm.tm_hour ^ tm.tm_hour)
| (ltm.tm_mday ^ tm.tm_mday)
| (ltm.tm_mon ^ tm.tm_mon)
| (ltm.tm_year ^ tm.tm_year)))
break;
}
if (! __gmtime_r (<, >m))
break;
diff = tm_diff (<m, >m);
}
#endif
if (diff < 0)
{
add (1, *p = L_('-'));
diff = -diff;
}
else
add (1, *p = L_('+'));
diff /= 60;
DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
}
数値の符号と数値を別々に出力している。 符号を出力するaddはこういうマクロで
add
glibc/time/strftime_l.c at master · bminor/glibc
#define add(n, f) \
do \
{ \
int _n = (n); \
int _delta = width - _n; \
int _incr = _n + (_delta > 0 ? _delta : 0); \
if ((size_t) _incr >= maxsize - i) \
return 0; \
if (p) \
{ \
if (_delta > 0) \
{ \
if (pad == L_('0')) \
memset_zero (p, _delta); \
else \
memset_space (p, _delta); \
} \
f; \
p += _n; \
} \
i += _incr; \
} while (0)
+
もしくは-
を出力するときに
zに対する幅指定とパディング文字の影響を受けてしまっている
(上記のコード片にあるwidthという変数が幅指定の結果を保持している)ために
たとえば
%04z
なら、+
を4桁のスペースを使い、かつパディングは0
として出力するので
kbk@toybox4:~$ ./a.out '%04z'
Result string is "000+0900"
という結果となり、
%4z
であれば
+
を4桁のスペースを使い、かつパディングはスペースとして出力するので
Result string is " +0900"
となる。
“%4z” だと " +0043" になる
が謎のままだけどとりあえずここまで
colon
ところでところで strftimeについて調べている途中で strftimeのglibc拡張では日付0埋めなどを簡単に削れる - stefafafan の fa は3つです という記事を見つけていて、そこにこんなことが書かれていた
コロンの数でタイムゾーンオフセットのフォーマットが変わる
$ date +%z%t%:z%t%::z%t%:::z
+0900 +09:00 +09:00:00 +09
glibcのstrftimeの実装を追いかけてて これをやっているような部分は見かけなかったがなあ? 思いつつも coreyrilsのdateのソースを見ると
coreutils/src/date.c at master ・ coreutils/coreutils ・ GitHub
%z +hhmm numeric time zone (e.g., -0400)\n\
%:z +hh:mm numeric time zone (e.g., -04:00)\n\
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)\n\
%:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)\n\
あった。 じゃあどこでその処理をとさらに追いかけると、 実はdateはglibcのstrtimeを使わずにgnulibのものを使っていた。 そっちには
strftime.c ≪ lib - gnulib.git - gnulib - GNU portability library
case L_(':'):
/* :, ::, and ::: are valid only just before 'z'.
:::: etc. are rejected later. */
for (colons = 1; f[colons] == L_(':'); colons++)
continue;
if (f[colons] != L_('z'))
goto bad_format;
f += colons;
goto do_z_conversion;
case L_('z'):
colons = 0;
do_z_conversion:
if (tp->tm_isdst < 0)
break;
とか
switch (colons)
{
case 0: /* +hhmm */
DO_TZ_OFFSET (5, 0, hour_diff * 100 + min_diff);
case 1: tz_hh_mm: /* +hh:mm */
DO_TZ_OFFSET (6, 04, hour_diff * 100 + min_diff);
case 2: tz_hh_mm_ss: /* +hh:mm:ss */
DO_TZ_OFFSET (9, 024,
hour_diff * 10000 + min_diff * 100 + sec_diff);
case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
if (sec_diff != 0)
goto tz_hh_mm_ss;
if (min_diff != 0)
goto tz_hh_mm;
DO_TZ_OFFSET (3, 0, hour_diff);
default:
goto bad_format;
}
というコードがある。 が、ほかの部分は(たぶん)glibcのと同じもので、 なぜにわざわざgnulibに入れているんだろうという 気がしないでもない。
for
さらにつづき
のtranscriptの
there was one other added thing to B which was I saw Johnson’s semi colon version of the for loop and I put that in I stole it
に関して。
上記のtransription、実は一部欠けていて
There was one other added thing to B which was I saw Johnson’s semi colon version of the for loop and I put that in B, I stole it
というのが本当(?)らしい。 さてここで登場するJohnsonさん、名前が出てくるのはここだけで ほかの部分には見当たらないのだけど、 YACCその他の作者であるところのこの人ではなかろうか
と思って調べてみたところ、彼のエントリにはこれという情報は見当たらなかったものの
にこんな記述があった
Another form was popularized by the C language. It requires 3 parts: the initialization (loop variant), the condition, and the advancement to the next iteration. All these three parts are optional. This type of “semicolon loops” came from B programming language and it was originally invented by Stephen Johnson.[2]
The condition part checks a certain condition and exits the loop if false, even if the loop is never executed. If the condition is true, then the lines of code inside the loop are executed.
2.Thompson, Ken. VCF East 2019 - Brian Kernighan interviews Ken Thompson. YouTube. Archived from the original on 2021-12-12. Retrieved 2020-11-16. “I saw Johnson’s semicolon version of the for loop and I put that in [B], I stole it.”
C(およびそこから派生した) for (;;)
という形式の発明者は
Johnsonということらしい。が
- The Programming Language B : Stephen C. Johnson, Brian W. Kernighan : Free Download, Borrow, and Streaming : Internet Archive
- The Programming Language B
- Stephen Curtis Johnson: Geek of the Week
forのあるBってどこよって話と どういう経緯と考えてこの形式が生み出されたかの情報はなし。
WG 14
__far
とか__code
とか
新刊近刊
ゼロから始めるLean言語入門
お知らせを公開しました "新刊『ゼロから始めるLean言語入門 ― 手を動かして学ぶ形式数学ライブラリ開発』 の発売を9/4に予定しています https://t.co/ud4i3I6B2G
— lambdanote (@lambdanote) August 29, 2025
というわけで9月4日に新刊発売です。ついにLeanの本がでます! Mathlibもgrindもあります! 今月正式リリースになったばかりの4.22.0です! https://t.co/vgUYcBJ6o4
— 専門性・売上・原稿 (@golden_lucky) August 29, 2025
夜桜四重奏
本屋のコミックのコーナーで最終巻が並んでいたのを見て完結を知った。
アニメやったのって何年前だっけ?
Build a Reasoning Model
LLMs give answers.
— Manning Publications (@ManningBooks) August 29, 2025
Reasoning models explain why.@rasbt’s Build a Reasoning Model (From Scratch) shows you how to boost a pre-trained LLM’s reasoning ability step by step.
50% off with code raschka2ML through Sept 12th: https://t.co/wDsseiOnIz pic.twitter.com/PLZ0OVFuA7
Lisp from Nothing, Second Edition
awk
gawk
Question on gawk usage: why is -M required for 64-bit safe addition?
9223372036854775807
という中身のファイルを
./gawk '{ sum += $1 }; END { print sum }'
というスクリプトに食わせても 9223372036854775808. という結果になったのはなんでという話らしい (が、「期待していた結果」が9223372036854775806とは?)
これ、awk(gawk)では数値には「整数型」というものはなくて すべて倍精度浮動小数点数になるので、 「整数型」が64bitの環境であっても 大きな整数を正しく表現できない(場合がある) って奴だろう
(log 9223372036854775807)
43.66827
(/ (log 9223372036854775807)
(log 10))
18.96489
(/ (log 9223372036854775807)
(log 2))
63.0
9223372036854775808は「たまたま」正確に倍精度浮動小数点数で表すことのできる整数
(expt 2 63)
9223372036854775808
.
FORTRAN Compiler on IBM 704
- The arithmetic translator-compiler of the IBM FORTRAN automatic coding system | Communications of the ACM
- Assembly listing of transcription - Software Preservation Group
- FORTRAN II
Hugoメモ
Release v0.149.0 · gohugoio/hugo