math - 如何手动将双精度(浮点数)乘以整数类型(32 位、64 位、128 位等)
问题描述
我正在尝试手动实现我使用两个 ulong 创建自己的双精度和 128 位整数之间的乘法。
我的理解如下:
1.将双精度数分解为有效数和指数。确保有效数字归一化。
2. 将有效数字与我的 uint128 相乘。这将给我 256 位数。
3. 将我的 256 位数按从双精度中提取的指数移位。
4.如果值超过128位,那么我溢出了。
我觉得我非常接近,但我错过了一些东西。可以说我有以下示例。我正在存储一个值为 2^127 的 uint128,我想将它乘以 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
我正在使用从c# 中的 double 中提取尾数和指数的代码来获取我的尾数和指数。我可以使用这些值正确地将 8E-6 作为双精度值返回。
有谁知道我在这里做错了什么?如果我使用 .8 而不是 8E-6,我的值会更好。
解决方案
我在这里做错了什么?
double multiplier
没有 0.000008 的算术值。它的二进值 接近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,最接近double
8E-6 的是 ( @Patricia Shanahan ) 0.000007999999999999999637984894607090069484911509789526462554931640625。
乘以 2 127正好是
1361129467683753 792259819967610880.0
所以乘法似乎是一倍的,也许是四舍五入?
推荐阅读
- ssl-certificate - 如何在赛普拉斯 POST 请求中传递 SSL 证书
- r - 如何访问远程主机上的 dockerized 应用程序
- python - 用于多表连接的 SQL Alchemy 映射器
- php - 如何使用 PHP 在新窗口中添加超链接
- python - 在tkinter中调整高度时如何修复输入框?
- python - 使用 Azure KeyVault 的 mTLS?
- javascript - Xpath 不识别锚标签?
- python - 如何使用 Selenium 和 Python 从 div 类中提取文本
- wordpress - 如何使古腾堡块翻译工作?
- android - Android 何时广播 ACTION_DATE_CHANGED?