ときどきの雑記帖 RE* (新南口)
真と偽と R
まだつづくこのネタ。
Ruby
Ruby では数値の 0 が偽にならない。
irb(main):001:0> 0 ? "true" : "false"
=> "true"
irb(main):002:0> nil ? "true" : "false"
=> "false"
なもんで、「宇宙船演算子」をつなげて書くときにちょっと面倒がある。
Numeric#nonzero? (Ruby 2.7.0 リファレンスマニュアル)
a = %w( z Bb bB bb BB a aA Aa AA A )
b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
b #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
↑の sort のブロックのところね。
実は大昔のRubyでは0も偽だったのだけど、途中で変わったのだよね (面倒なので具体的にいつだったのかは調べない)。
その辺を踏まえたうえで最近けっつまづいたこと。
(-1).downto(-54) do |n|
v = (2**n).to_f
puts "%7a %60.58f\n" % [v, v]
end
#irb(main):053:0> "%a" % (1 - 397.0 / 400)
#=> "0x1.eb851eb851e8p-8"
# 1 2 3 5 5
# 8 9012 3456 7890 1234 5678 9012 3456 7890 1234 5678 9012 3
# 1.1110_1011_1000_0101_0001_1110_1011_1000_0101_0001_1110_1
bitpat = 0b1011110001010000111010111100010100001110101111
n = -8
v = 0.0
while (bitpat != 0) do
if (bitpat & 1) == 1 #!!!
v += (2**n).to_f
printf "%60.58f\n", v
end
bitpat >>= 1
n -= 1
end
printf "%a\n", v
ビットをごにょごにょするこのスクリプトで最初は #!!!
のところを
if (bitpat & 1)
と書いてしまい(その割にwhileの方はちゃんと0と比較)、
出力を見て悩むことしばし(笑)。
GW-BASIC
GW-BASICのソースを見ていて興味深いものを発見。
GW-BASIC/GWMAIN.ASM at master · microsoft/GW-BASIC
; NOW CHECK HGHBIT CHARS, ? FOR PRINT
NTDATA:
INC BX ;IF SO SKIP IT
OR AL,AL ;IS THIS A KANA CHARACTER IN A BAD PLACE?
JNS SHORT ??L019
JMP KLOOP ;MOVE TO THE NEXT CHARACTER
??L019:
MSBでカナかどうか判定してるんですかね。
GW-BASIC/GWEVAL.ASM at master · microsoft/GW-BASIC
NXTHEX: ADD BX,BX ;SHIFT RIGHT FOUR BITS
ADD BX,BX
ADD BX,BX
ADD BX,BX
OR AL,BL ;OR ON NEW DIGIT
MOV BL,AL ;SAVE BACK
XCHG BX,DX ;GET TEXT POINTER BACK IN [H,L]
DEC CH
JNZ SHORT LOPHEX ;KEEP EATING IF NOT TOO MANY DIGITS
;IF NOT INPUT STATEMENT GOTO OVFLW ERROR FROM HERE, ELSE PASS BACK ERROR
ADD BX,BX の4回繰り返しだと「左」4ビットシフトのような気がするんだけど、 この世界ではMSBが右にあるんだろうか。
追記(訂正)
SHIFT RIGHT FOUR BITS は 「右へ4ビットシフト」じゃなくて 「(1バイト中の)右側4ビットをシフト」 か。