双精度乘以整数精度
multiplication of double with integer precision
我有一个 3.4 的双精度。但是,当我将其乘以 100 时,它得到 339 而不是 340。似乎是由双精度引起的。我该如何解决这个问题?
谢谢
首先发生了什么:
- 3.4 不能完全表示为二进制分数。因此,实现选择可表示的最接近的二进制分数。我不确定它是否总是四舍五入到零,但在您的情况下,所代表的数字确实较小。
- 转换为整数 truncates,即使用具有较小绝对值的最接近的整数。
- 由于两次转化都偏向于同一方向,因此您总是会出现舍入误差。
现在你需要知道你想要什么,但你可能想使用对称舍入,即找到最接近的整数,无论是更小还是更大。这可以实现为
#include <cmath>
int round(double x) { std::floor(x + 0.5); } // floor is provided, round not
或
int round(double x) { return x < 0 ? x - 0.5 : x + 0.5; }
我不完全确定它确实四舍五入到零,所以如果您使用它,请验证后面。
如果您需要完全精度,您可能需要使用 Boost.Rational
.
您可以使用两个整数并将小数部分乘以乘数/10。
例如
int d[2] = {3,4};
int n = (d[0] * 100) + (d[1] * 10);
如果你真的想要小数点两侧的所有精度。确实取决于应用程序。
点值很少精确。遗憾的是,当浮点值转换为 C 中的整数时,该值将四舍五入为零。这意味着,如果您有 339.999999,则强制转换的结果将是 339。
为了克服这个问题,您可以从值中添加(或减去)"0.5"。在本例中,339.99999 + 0.5 => 340.499999 => 340(转换为 int 时)。
或者,您可以使用标准库提供的众多转换函数之一。
双精度值,因为 3.4 不是可表示为双精度(至少在普通机器上,并且大多数异国情调也是如此)。 你拥有的是一些价值非常接近 3.4。 乘法后,你有一些价值非常接近340。 但肯定不是399。
你在哪里看到399? 我猜你只是强制转换为int
,使用static_cast
,因为此操作截断为零。 其他操作可能会做什么您需要:以固定格式输出,在十进制,例如,舍入(在定义的实现中方式,但我知道的所有实现都使用圆到偶数默认情况下);函数round
舍入到最近,舍入在中途情况下远离零(但您的结果不会接近中途的任何地方)。 这是在 中使用的舍入商业应用。
真正的问题是你在做什么,需要一个确切的积分值。 根据应用的不同,可能会更多适合使用int
或long
,将实际值缩放为必要(即存储实际值的 100 倍,或无论如何),或某种十进制算术包,而不是比使用double
.
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何打印boost多精度128位无符号整数
- C 字符串返回字符串的整数/双精度/长整型值
- 如何检测 std::vector::emplace_back 上的隐式转换损失整数精度
- 如何防止双精度值到整数的隐式转换
- 如何解决隐式转换丢失整数精度:'size_t'(又名"无符号长")到'int'警告?
- 野牛/flex:计算器将双精度值解释为整数,所以我添加了 YYSTYPE 双精度 #define 但我有多个编译错误
- 为什么输出是整数而不是双精度?
- 从字符串转换为双精度和整数 - C++
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- C++,遇到将双精度转换为整数的问题
- 用双精度除以整数
- 使用整数初始化列表初始化长双精度的向量
- C++:使用一对(cpp_int,int)整数作为无序映射中的键(其中cpp_int是boost多精度整数)
- 双精度/整数模板函数的向量
- 使用 Boost.Random 从种子生成多精度整数
- 任意精度整数词汇中的肢体
- C++将升压多精度整数转换为 64 位长度十六进制
- 如何通过 JNI 设置 java 类的双精度/整数类型的值
- 将输入验证为双精度/整数的函数