如何从浮点数中提取并进分数



现在,浮点数和双精度数,虽然它们可以近似任何类型的数字(虽然也可以说是整数,浮点数只是更精确),它们在内部被表示为二进制小数。例如,十分之一近似为

0.00011001100110011... (... only goes to computers precision, not infinity)

现在,任何有有限位的二进制数在数学中被称为dyadic fraction表示(与p进无关)。这意味着你把它表示成分数,分母是2的幂。例如,假设我们的计算机将十分之一近似为0.00011。它的二进分数是3/323/(2^5),接近十分之一。现在是我的技术问题。从浮点数中提取并进分数的最简单方法是什么?

无关注意:如果你想知道为什么我想这样做,那是因为我在Haskell中创建了一个超现实的数字库。并进分数很容易转换成超现实数,这就是为什么二进制很容易转换成并进数的原因,(我肯定会遇到有理数的麻烦。)

decodeFloat函数似乎对此很有用。从技术上讲,你也应该检查floatRadix是2,但据我所知,这在GHC中总是如此。

要小心,因为它不会简化尾数和指数。这里,如果我计算decodeFloat (1.0 :: Double),我得到的指数是-52,尾数是2^52,这不是我所期望的。

同时,toRational似乎产生了一个二进分数。不过,我不确定情况是否总是如此。

保持数字为二进制并转换为十进制以显示

二进制数都是动态的。小数点后的数字代表分母的2的幂次数,没有小数点的计算数是分子。这是二进制数。

超现实数在二进制中有一个理想的表示。我称它们为"sinary"。它是这样的:0不是一个数字1s等于010是- 111是1100等于- 2105等于- 1/2110是一半111等于2…等等…

,因此您可以看到标准二进制计数在以sinary计算时匹配数值的超现实出生顺序。确定sinary数值的方法是1在右边,0在左边。从+/-1开始,然后是1/2 1/4 1/8,等等。对于1,符号等于+,对于0,符号等于-

示例:求值sinary

1011011s 
-> is the 91st surreal number (because 64+16+8+2+1 = 91)
-> with a value of −0.28125, because...
1011011
NLRRLRR
+-++-++
+ 0 − 1 + 1/2 + 1/4 − 1/8 + 1/16 + 1/32
= 0 − 32/32 + 16/32 + 8/32 − 4/32 + 2/32 + 1/32
= − 9/32

超现实数形成了一棵二叉树,因此存在一种理想的二进制格式,根据左/右模式匹配它们在树上的位置来达到数字。将1赋给右边,0赋给左边。那么超现实数的出生顺序就等于这种表示法的二进制数。即:以单位制表示的第15个超现实数字值是标准二进制计数中的第15个数字表示。sinary的值是超现实标签值。从表示法中去掉前导位,并根据数字在第一个数字之后以1或0开头开始添加+1或-1。然后,一旦位翻转,开始根据位值1/0使用+或-值加减二分之一的值(1/2,1/4,1/8等)。

我已经测试了这种格式,它似乎工作得很好。还有一些其他的秘密……例如,任何正弦表示的左和右都是相同的二进制格式,尾部分别被截断到最后一个0和最后一个1。为了执行Conway所要求的递归函数,不需要将十进制转换为动态。

最新更新