试图弄清楚这是如何工作的,但我无法理解我所代表的内容。我知道我们分配一个unsigned long long因为它包含与float相同的位数。但我到底代表什么?
我最好的解释是,我们试图将 double 数字转换为 unsigned long long int,因为它们具有相同的位数。看来最好的方法是取消引用我们设置的指针?
任何帮助将不胜感激!
void printDouble(double d) {
unsigned long long int i = *(unsigned long long int *)&d;
for (int j = 63; j >= 0; j--) {
std::cout << ((i >> j) & 1);
if (j == 63) std::cout << " ";
else if (j == 52) std::cout << " ";
}
Run Code Online (Sandbox Code Playgroud)
}
所以我有点无奈。我想我了解如何对 IEEE-754 数字进行加法,但我在减法方面遇到了很大的问题。我感觉我的想法是对的,但我想和大家确认一下。
所以我们有以下两个 IEEE-754 编号:
x: 0 1000 0010 100 1000 0000 0000 0000 0000
y: 0 1000 0011 010 1001 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
由于我们必须是正数并且我们想减去它们,所以我的想法是取 y,反转尾数并计算
x+(-y)
一位导师告诉我,这是不正确的,我必须保持数字为正,然后减去它们。为什么以及如何他没有告诉我。
有人可以告诉我这样做的正确方法是什么吗?
我对 xy 方式的想法:
我正在看几本教科书,包括Trefethen 和 Bau 的《数值线性代数》,在浮点算术部分中,他们似乎说在 IEEE-754 中,归一化浮点数采用形式.1.... X 2^e。也就是说,假定尾数在 0.5 到 1 之间。
然而,在这个流行的在线浮点计算器中,解释了标准化浮点数的尾数在1和2之间。
有人可以告诉我哪个是正确的方法吗?
我有一个浮点变量,每一步递增 0.1。我想将其转换为 16 位固定值,其中有 5 位小数部分。为了做到这一点,我有下面的代码片段:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<16> mybits;
string mystring;
float x = 1051.0;
for (int i = 0; i < 20; i++)
{
mybits = bitset<16>(x*32);
mystring = mybits.to_string<char, string::traits_type, string::allocator_type>();
cout << x << "\t" << "mystring: " << mystring << '\n';
x += 0.1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,结果是这样的:
1051 mystring: 1000001101100000
1051.1 mystring: 1000001101100011
1051.2 mystring: 1000001101100110
1051.3 mystring: 1000001101101001
1051.4 mystring: 1000001101101100
1051.5 …Run Code Online (Sandbox Code Playgroud) 考虑以下 Java 代码:
public class Program {
public static void main(String args[]) {
double number = Double.MAX_VALUE;
String formattedNumber = String.format("%f", number);
System.out.println(formattedNumber);
}
}
Run Code Online (Sandbox Code Playgroud)
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000.000000
考虑等效的 C# 代码:
public class Program
{
public static void Main(string[] args)
{
double value = double.MaxValue;
Console.WriteLine(value.ToString("F"));
}
}
Run Code Online (Sandbox Code Playgroud)
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234 32132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334 8274797826204144723168738177180919299881250404026184124858368.000
鉴于 的最大值Double为 1.7976931348623157E+308,据我所知,Java 输出是正确的;即浮点值实际上表示一个整数,其中前 17 位数字为 17976931348623157,后跟 292 个零。
注意:在 C# 中转换double为BigInteger会产生相同的结果:
BigInteger value = (BigInteger)double.MaxValue;
Console.WriteLine(value);
Run Code Online (Sandbox Code Playgroud)
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234 32132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334 8274797826204144723168738177180919299881250404026184124858368
问题
我正在做一些操作,但没有找到确切的解释来解释为什么我发现了特定的行为。语境:
最小工作示例:
#include <stdio.h>
#include <stdint.h>
int main()
{
printf("Operations with comas \n");
uint16_t a = (uint16_t)((24.2 - 0)/0.1); /* 241 Incorrect*/
uint16_t b = (uint16_t)((24.2 - 0.0)/0.1); /* 241 Incorrect */
uint16_t c = (uint16_t)((float)(24.2 - 0)/0.1); /* 242 Correct */
uint16_t d = (uint16_t)(24.2/0.1); /* 241 Incorrect*/
uint16_t e = (uint16_t)(242.0); /* 242 Correct */
printf("a %u \n" , a);
printf("b %u \n" , b);
printf("c %u \n" , c);
printf("d %u \n" …Run Code Online (Sandbox Code Playgroud) 在浮点运算中计算两个数字的平均值的最准确方法是什么?让我们考虑一下最常见的双精度 64 位数字。
(a + b) / 2
a / 2 + b / 2
a + (b - a) / 2
这些计算平均值的方法可能会给出不同的结果,如下面的 C++ 代码所示:
double a = 1.2;
double b = 3.6;
double mean1 = (a + b) / 2.0;
double mean2 = a / 2.0 + b / 2.0;
double mean3 = a + (b - a) / 2.0;
cout << fixed << setprecision(20);
cout << "mean1: " << mean1 << endl;
cout << "mean2: " << mean2 …Run Code Online (Sandbox Code Playgroud) 考虑以下 C# 代码...
double x = Math.Round(72.6d, 2, MidpointRounding.ToZero);
double y = Math.Round(82.6d, 2, MidpointRounding.ToZero);
Run Code Online (Sandbox Code Playgroud)
x成为72.59并y成为82.6。
但为什么?通过这个IEEE754 转换器,两者的小数部分是相同的。那么为什么他们不给出相同的结果呢?
我可以通过执行以下操作来解决该问题(double)Math.Round(Convert.ToDecimal(72.6d), 2, MidpointRounding.ToZero)。但我更感兴趣的是知道为什么它似乎没有按预期工作的答案。
我遇到了一个似乎与平台相关的错误.我得到了clang ++和g ++的不同结果,但仅限于我的32-Debian Machine.我一直认为IEEE 754是标准化的,所有遵守标准的编译器都会有相同的行为.如果我错了,请告诉我,我对此非常困惑.另外,我意识到依赖浮点比较通常不是一个好主意.
#define DEBUG(line) std::cout <<"\t\t" << #line << " => " << line << "\n";
#include <iostream>
int main() {
double x = 128.0, y = 255.0;
std::cout << "\n";
DEBUG( x/y)
DEBUG( ((x/y) == 128.0/255.0))
DEBUG( (128.0/255.0) )
DEBUG( ((x/y)-(x/y)))
DEBUG( ((x/y)-(128.0/255.0)) )
DEBUG( ((128.0/255.0)-0.501961) )
std::cout << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出
[~/Desktop/tests]$ g++ float_compare.cc -o fc
[~/Desktop/tests]$./fc
x/y => 0.501961
((x/y) == 128.0/255.0) => 0
(128.0/255.0) => 0.501961
((x/y)-(x/y)) => 0
((x/y)-(128.0/255.0)) => …Run Code Online (Sandbox Code Playgroud)