如何手动将双精度(浮点数)乘以整数类型(32位,64位,128位等)

问题描述 投票:1回答:1

我正在尝试手动实现我使用两个ulongs创建的双精度整数和128位整数之间的乘法。

我的理解如下:1.将双精度分解为有效和指数。确保有效位数为normalized。2.乘以有效数和我的uint128。这将给我256位数字。3.通过从双精度码中提取的指数来移动我的256位数字。4.如果该值超过128位,则溢出。

我感觉自己非常接近,但是我缺少一些东西。可以说我有以下示例。我存储的uint128值为2 ^ 127,我想将其乘以8E-6。

uint128 myValue = new uint128(2^127);
double multiplier = 8E-6;
uint128 product = myValue * multiplier;

实际值或正确答案是1361129467683753853853498429727072.845824。所以我想将值1361129467683753853853498429727072作为我的128位整数。

问题是我的实现给了我1361129467683753792259819967610881

int exponent; // This value ends up being -69 for 8E-6
uint128 mantissa = GetMantissa(multiplier, out exponent); // This value ends up being 4722366482869645 after normalizing it.
uint256 productTemp = myValue * mantissa; // This value is something like 803469022129495101412490705402148357126451442021826560.
uint128 product = productTemp >> exponent. // this value is 1361129467683753792259819967610881

我正在使用extracting mantissa and exponent from double in c#中的代码来获取尾数和指数。我可以使用这些值将8E-6正确地重新获得两倍。

有人知道我在这里弄错了吗?如果我使用.8而不是8E-6,则我的值会更好。

math floating-point double mantissa
1个回答
0
投票

我在这里错了什么?

double multiplier的算术值为0.000008。它的dyadic value near 0.000008,到15-17个有效小数位。这种差异说明您没有达到您的期望。

1234567890123456
1361129467683753 853853498429727072.845824 - perceived product
1361129467683753 853853498429727072        - perceived rounded product
1361129467683753 792259819967610881        - product seen.

尝试使用十进制的[[精确值multiplier,例如0.0625(1.0 / 16)。


注意:

使用binary64,最接近[8E-6]的double是(@Patricia Shanahan)0.000007999999999999999637984894607090069484911509789526462554931640625。

乘以2

127就是

1361129467683753 792259819967610880.0
所以乘法似乎是一乘一舍,也许是四舍五入?
© www.soinside.com 2019 - 2024. All rights reserved.