什么是最大的"非浮动"整数,可以存储在IEEE 754 double类型而不会丢失精度?
我的问题是,是否保证所有整数值都具有完美的双重表示.
请考虑以下打印"相同"的代码示例:
// Example program
#include <iostream>
#include <string>
int main()
{
int a = 3;
int b = 4;
double d_a(a);
double d_b(b);
double int_sum = a + b;
double d_sum = d_a + d_b;
if (double(int_sum) == d_sum)
{
std::cout << "Same" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
对于任何架构,任何编译器,任何值a和b?保证这是真的吗?i转换为的任何整数是否double总是表示为i.0000000000000和不表示为,例如,i.000000000001?
我尝试了其他一些数字并且它总是如此,但无法找到关于这是巧合还是设计的任何信息.
注意:这与这个问题(除了语言)不同,因为我添加了两个整数.
我意识到无论什么时候处理IEEE 754双打和浮点数,有些数字都无法表示,尤其是当一个数字试图表示小数点后面有大量数字的数字时.这是很好理解但我很好奇,如果在双(或浮点)的MIN/MAX范围内有任何整数不能表示,因此需要四舍五入到最接近的可表示的IEEE 754表示?
例如,非常大的数字有时以双精度或浮点数表示,即使它们是整数.显然使用直接向上的int64或一些这样的大整数数据类型会更好,但是人们仍然经常使用双数来表示大数.
有没有可以被称为不可表示的数字,或者你能给我一个数学上的原因,为什么它不会成为问题?
在执行数学运算之后,比如乘以两个整数,是否可以使用C++访问CPU中的溢出标志寄存器?如果没有其他快速方法来检查溢出?
我不想在一个不精确的值是一个令人讨厌的时候引入浮点数,所以我有几个问题关于你何时可以安全地使用它们.
只要不溢出有效数字的数量,它们对整数是否精确?这两个测试总是正确的:
double d = 2.0;
if (d + 3.0 == 5.0) ...
if (d * 3.0 == 6.0) ...
Run Code Online (Sandbox Code Playgroud)
您可以依赖什么数学函数?这些测试总是如此:
#include <math.h>
double d = 100.0;
if (log10(d) == 2.0) ...
if (pow(d, 2.0) == 10000.0) ...
if (sqrt(d) == 10.0) ...
Run Code Online (Sandbox Code Playgroud)
这个怎么样:
int v = ...;
if (log2((double) v) > 16.0) ... /* gonna need more than 16 bits to store v */
if (log((double) v) / log(2.0) > 16.0) ... /* C89 */
Run Code Online (Sandbox Code Playgroud)
我想你可以总结这个问题:1)浮点类型是否可以保存所有整数的精确值,直到float.h中有效数字的数字?2) …
我开始学习Rust.我试过这个程序:
fn main() {
let a = 5;
let b = 5.5;
let k = a + b;
println!("{}", k);
}
Run Code Online (Sandbox Code Playgroud)
它显示此错误:
error[E0277]: cannot add a float to an integer
--> src/main.rs:4:16
|
4 | let k = a + b;
| ^ no implementation for `{integer} + {float}`
|
= help: the trait `std::ops::Add<{float}>` is not implemented for `{integer}`
Run Code Online (Sandbox Code Playgroud)
代码错了吗?
什么是(连续的)整数的确切范围,可以表示为double(resp.浮点?)我问的原因是因为我对这样的问题感到好奇,因为会发生精度损失.
那是
m,m+1不能精确表示为double(resp.浮点数)?-n,-n-1不能精确表示为double(resp.浮点数)?(可能与上面相同).这意味着,每一个之间的整数-n和m具有精确的浮点表示.我基本上都在寻找[-n, m]浮动和双打的范围.
我们将范围限制为标准IEEE 754 32位和64位浮点表示.我知道浮点数有24位精度,双精度数有53位(都带有隐藏的前导位),但由于浮点表示的复杂性,我正在寻找权威的答案.请不要挥手!
(理想的答案将证明,所有的整数从0到m的表达,这m+1是没有的.)
public class SimplePrint {
public static void main(String[] args) {
long i = System.currentTimeMillis();
System.out.println(i);
float h = 0.0f;
i -= h;
System.out.println(i);
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1477904636902
1477904695296
但是当我改变h变量的数据类型时
public class SimplePrint {
public static void main(String[] args) {
long i = System.currentTimeMillis();
System.out.println(i);
double h = 0.0f;
i -= h;
System.out.println(i);
}
}
Run Code Online (Sandbox Code Playgroud)
输出改变了:
1477904677513
1477904677513
为什么是这样 ???
Rust的f64类型提供了函数round(),它舍入到最接近的整数,但它返回一个f64.Math.round(double)另一方面,Java会返回一个long.我可以打电话round()然后再投i64,但这能保证我得到正确的结果吗?在这里,"正确"意味着获得最接近的i64- Java round()返回"最接近的长".
我需要将整数舍入为另一个整数的最接近的倍数.在100的倍数的情况下结果的示例:
等等.
我提出了以下代码,它有效,但感觉"脏":
int RoundToMultiple(int toRound, int multiple)
{
return (toRound + (multiple / 2)) / multiple * multiple;
}
Run Code Online (Sandbox Code Playgroud)
这依赖于整数除法的截断属性以使其起作用.我可以指望这个代码是可移植的吗?是否有任何编译器设置,这将无法给我所需的结果?如果有,我怎样才能以便携方式获得相同的结果?
如果需要更好的答案,可以假设倍数将是10的幂(包括1的倍数).数字也可以假设都是正数.