ときどきの雑記帖 RE* (新南口)
人間の証明
. で話にならない
Excelが計算できない数の組み合わせと条件及び、その対処方法について - Qiita
例によっていつものアレだろ? と思ってたのだけど、 ちょっと調べてみると問題の数字はなかなかに興味深かった。
Excel ではなく Rubyでだけどまあ大きな違いはなかろうということで
irb(main):001:0> v = 0.0075
irb(main):002:0> "%a" % v
=> "0x1.eb851eb851eb8p-8"
irb(main):003:0> v.round(3)
=> 0.008
とりあえず目論見通りの結果になる。そして Ruby のfloatクラスには prev_float というメソッドがあるのでそれを使って一つ前の値で試すと
irb(main):004:0> "%a" % v.prev_float
=> "0x1.eb851eb851eb7p-8"
irb(main):005:0> v.prev_float.round(3)
=> 0.007
本当にギリギリのところだったんですな。
もうちょっと詳しく見ると
irb(main):008:0> "%b" % (0x1eb851eb851eb8 * 0x1f4)
=> "11101111111111111111111111111111111111111111111111111101100000"
irb(main):009:0> "%b" % (0x1eb851eb851eb7 * 0x1f4)
=> "11101111111111111111111111111111111111111111111111110101101100"
で、見やすく(?)するとこう。
1.1101_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1011_00000
d f f f f f f f f f f f f b
1.1101_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110_1011_01100
d f f f f f f f f f f f e b
仮数部を切り詰めるときの0捨1入で桁上りが連鎖的に起きるか起きないかの違いと
(3970/4000 - 1
は 0x1.eb851eb851eb7p-8 よりもう少し絶対値が小さいので
ああなると。
オマケ
英語版うぃきぺにはこんなページが。
Numeric precision in Microsoft Excel - Wikipedia
暦
ちょっと前に話題になったこれに関連して。
1582年10月4日の翌日は? - Web Programmerメモ で色々調べているんだけど、なんでドキュメントにあたらないんですかね。
まあそれはさておき GregorianCalendar (Java Platform SE 8 ) を見てたら気になる記述が。
GregorianCalendarは、グレゴリオ暦とユリウス暦をサポートするハイブリッド・カレンダで、単一の変わり目を処理します。 この変わり目は、デフォルトでは、グレゴリオ暦が制定された日(一部の国では1582年10月15日、その他の国ではそれ以後)に対応しています。 切換え日は、呼出し側でsetGregorianChange()を呼び出して変更できます。
歴史的に、グレゴリオ暦を最初に採用した国々では、1582年10月4日(ユリウス歴)のあとに1582年10月15日(グレゴリオ歴)が続きました。 このカレンダはこれを正確にモデル化しています。グレゴリオ暦への切換え日の前は、GregorianCalendarではユリウス暦を実装しています。 グレゴリオ暦とユリウス暦の唯一の違いはうるう年のルールです。ユリウス暦は4年ごとにうるう年を指定しますが、グレゴリオ暦では、 400で割り切れない世紀の初年をうるう年にしません。
「世紀の最初の年」って 00年じゃなくて01年じゃなかったっけ?
c世紀(cは正の整数)とは、西暦(c×100 - 99)年から西暦(c×100)年までの100年間をいう。例えば、20世紀は1901年から2000年までをいう[1]。
ですよねー。
念のため英文も見ておくか
GregorianCalendar (Java SE 14 & JDK 14)
Historically, in those countries which adopted the Gregorian calendar first, October 4, 1582 (Julian) was thus followed by October 15, 1582 (Gregorian). This calendar models this correctly. Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.
ん?
century yearの意味・使い方・読み方 | Weblio英和辞書
ほかの言語では
datetime — 基本的な日付型および時間型 — Python 3.9.0 ドキュメント
date オブジェクトは、両方向に無期限に拡張された現在のグレゴリオ暦という理想化された暦の日付 (年月日) を表します。
class Date (Ruby 2.7.0 リファレンスマニュアル)
Date::ENGLAND (Ruby 2.7.0 リファレンスマニュアル)
PHP はわかんなかったのでパス。
日付の扱いは難しい(面倒くさい)
↑の記事の数日後にこんな記事を見かけた。
- (1) Why is subtracting these two times (in 1927) giving a strange result? : programming
- java - Why is subtracting these two times (in 1927) giving a strange result? - Stack Overflow
NaN Boxing
【ニュース】 R 界隈からの Apple silicon での Fortran 情報 - fortran66のブログ
を読んでいたらこんなくだりが。
しかし、興味深いのは R では NaN のビット配列が一意でないことを利用して、NaN 中特定の bit 列に意味を与えてデータなし NA (not available) を表すことに利用していたようなのですが、それが Apple Silicon の高速演算モードで地雷となって 問題になっているらしいことです。以前 mruby が NaN の bit 列の一部を固有の意味で利用していると聞いて、 将来の禍根になりそうだなと思ったら、同じようなことがこんな所で爆発していました。
これを避けるため浮動小数点演算厳密モードで計算すると多分計算が少し遅くなると思います。
グスタフソンがカーンの IEEE754 を批評して NaN がビット列を無駄にし過ぎていて、こういう冗長性がありすぎるとハック (やっつけ仕事)されて不正利用されると言っていた気がしますが、全くその通りになっていて草生えます。
大昔、68000でアドレスレジスタ-の最上位8ビットをタグに使ったら後継プロセッサーで 痛い目みた。というのと同じ類の話ですかね。
ところで、NaN Boxing でググったら上位に出てくるところで言及されていたり 自身も上位に出てくるサイト(はてなブログ)が限定公開になってて読めないんですがそれは。
NaN boxingとsizeof(mrb_value) - mirichiの日記
NaN boxingについて日本語の情報はほとんどないが、ここに大変わかりやすく書いてあるので興味がある人は見てみるのをオススメ。 http://d.hatena.ne.jp/Constellation/20110910/1315586703
mrubyのJITではオブジェクトの内部表現としてNaN Boxingを採用しています。 NaN boxingについては、Constellationさんの解説記事 を読んでいただくのが良いと思います。
複数精度の浮動小数点を取り扱うための手法NaN Boxingについて - FPGA開発日記
翻訳記事
結構長い英文記事だったので(微妙な部分があるとはいえ)翻訳はありがたいのだけど、 色々大丈夫なんかね権利関係とか。
ところで
ダイクストラの画期的な著書『A Discipline of Programming (プログラミングの規律)』は1976年に出版されました32。
『プログラミングの規律 (A Discipline of Programming)』の序文には、率直な告白で締めくくられています。
1990年に出版された、ダイクストラの『述語計算とプログラムの意味論 (Predicate Calculus and Program Semantics)』
この辺の本、邦訳出ていなかったっけ? 違う邦題で。