将两个整数除以不强制转换为双精度
Dividing two integer without casting to double
我有两个整数变量,partial
和 total
。这是一个进步,所以partial
从零开始,一个接一个地上升到total
的值。
如果我想得到一个指示进度的分数值(从 0.0 到 1.0(,我可以执行以下操作:
double fraction = double(partial)/double(total);
但是,如果总数太大,转换为双倍可能会丢失信息。
实际上,丢失的信息量是可以容忍的,但我想知道是否有一种算法或 std 函数来获取两个值之间的分数,丢失的信息更少。
显而易见的答案是将partial
乘以某个比例因子; 100
是一个常见的选择,因为除法随后给出的百分比为整数值(向下舍入(。 问题是,如果值是如此之大以至于它们无法在double
中精确表示,有乘以比例因子也很有可能溢出。 (就此而言,如果它们那么大,则初始值将在大多数计算机上溢出int
。
是的,有一种算法丢失的信息更少。假设您要找到最接近分数数学值的double
值,则需要一个能够容纳 total << 53
的整数类型。您可以创建自己的库或使用像GMP这样的库。然后
- 缩放
partial
以便(total << 52) <= numerator < (total << 53)
,其中numerator = (partial << m)
- 设
q
为整数商numerator / total
和r = numerator % total
- 让
mantissa = q
如果2*r < total
,= q+1
如果2*r > total
,如果2*r == total
,mantissa = q+1
如果你想四舍五入一半,= q
如果你想四舍五入一半,如果你想四舍五入一半,两者中的偶数,如果你想四舍五入到偶数 -
result = scalbn(mantissa, -m)
大多数时候,你得到的值与(double)partial / (double)total
相同,一个最低有效位的差异可能不太罕见,两个或三个LSB的差异也不会让我感到惊讶,但很少见,更大的差异不太可能(也就是说,有人可能很快就会举一个例子(。
现在,值得付出努力吗?通常不会。
如果你想要分数的精确表示,你会有某种结构,将分子和分母作为整数,并且,对于唯一的表示,你只需分解出最大公约数(零的特殊情况(。 如果您只是担心重复操作后浮点表示可能不够准确,则需要找到一些数值分析课程,因为该问题严格来说不是编程问题。 有比其他人更好的方法来计算某些结果,但我不能真正进入它们(我从来没有做过课程,只是阅读它(。
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何从字符串转换为双精度*
- C++如何将字符串逐行转换为双精度
- 如何防止双精度值到整数的隐式转换
- 如果存在从"双精度"到"T"的转换,则禁用构造函数
- 在C++中将字符串转换为双精度,而无需科学记数法
- 使用从文件(stod、strtod、atof)中提取的数据C++从字符串转换为双精度.csv
- 如何在C++中将字符串转换为双精度?
- 将双精度值转换为 char 变量时字符串流如何工作
- 从二进制流中读取时,将双精度变量的地址转换为 char* 意味着什么?
- 在 c++ 中从双精度转换为字符串
- 如何在C++中将无符号字符缓冲区转换为双精度?
- 从字符串转换为双精度和整数 - C++
- 如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- 表达式中应用的转换(双精度为整数)
- 无法转换双精度 - 新运算符
- C++类型转换双精度