我知道C和C++标准留下了语言实现的许多方面 - 仅仅因为如果存在具有其他特征的体系结构,那么为它编写符合标准的编译器是非常困难或不可能的.
我知道40年前任何电脑都有自己独特的规格.但是,我不知道今天使用的任何架构:
CHAR_BIT != 8
signed
不是两个补充(我听说Java有这个问题).我问的原因是我经常向人们解释C++不强制要求任何其他低级方面如固定大小的类型†.这很好,因为与其他语言不同,它使你的代码在正确使用时可以移植(编辑:因为它可以移植到更多架构而不需要模拟机器的低级方面,例如符号+幅度架构上的二进制补码算法) .但我感到很难过,我自己也无法指出任何特定的架构.
所以问题是:哪些架构具有上述属性?
† uint*_t
s是可选的.
我的问题是,是否保证所有整数值都具有完美的双重表示.
请考虑以下打印"相同"的代码示例:
// 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
?
我尝试了其他一些数字并且它总是如此,但无法找到关于这是巧合还是设计的任何信息.
注意:这与这个问题(除了语言)不同,因为我添加了两个整数.
浮点是在C中定义的实现.因此没有任何保证.
我们的代码需要是可移植的,我们正在讨论在我们的协议中使用IEEE754浮点数是否可以接受.出于性能原因,如果我们不必在发送或接收数据时在固定点格式之间来回转换,那将是很好的.
虽然我知道平台和架构之间可能存在关于long
或的大小的差异wchar_t
.但我似乎无法找到任何具体的float
和double
.
到目前为止我发现字节顺序可能在大端平台上被反转.虽然有不带浮动包含代码,其中点支撑平台float
和double
甚至无法链接.否则平台似乎坚持IEEE754单精度和双精度.
那么可以假设浮点数在IEEE754可用时安全吗?
编辑:回应评论:
你对"安全"的定义是什么?
安全我的意思是,一个系统上的位模式在另一个系统上意味着相同(在字节旋转之后处理字节序).
我一直在寻找如何将big-endian转换为little-endians.但我找不到任何可以解决我问题的好处.似乎有很多方法可以进行这种转换.无论如何,以下代码在big-endian系统中正常工作.但是我应该如何编写转换函数,以便它也适用于little-endian系统?
这是一个功课,但它只是一个额外的,因为在学校运行大端系统的系统.这只是我很好奇,并希望它也可以在我的家用电脑上工作
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream file;
file.open("file.bin", ios::in | ios::binary);
if(!file)
cerr << "Not able to read" << endl;
else
{
cout << "Opened" << endl;
int i_var;
double d_var;
while(!file.eof())
{
file.read( reinterpret_cast<char*>(&i_var) , sizeof(int) );
file.read( reinterpret_cast<char*>(&d_var) , sizeof(double) );
cout << i_var << " " << d_var << endl;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
解决了
所以Big-endian VS Little-endian只是字节的逆序.我写的这个功能似乎无论如何都符合我的目的.我在这里添加它以防万一其他人将来需要它.这只是双倍,但是对于整数,要么使用建议的函数torak,要么可以通过使它仅交换4个字节来修改此代码.
double swap(double d)
{
double a;
unsigned char *dst = (unsigned …
Run Code Online (Sandbox Code Playgroud) 根据以下网站:http: //en.cppreference.com/w/cpp/language/types
"双精度浮点型.通常是IEEE-754 64位浮点型".
它说"通常".C++可以double
使用哪些其他可能的格式/标准?什么编译器使用IEEE格式的替代品?还是建筑?
这几乎是我在标题中的问题.对于其他任何使用它似乎完全不自然.
在研究这个时,我发现有基础10的硬件支持的历史例子,以及IBM POWER6和系统z9的更现代的例子.即使在这些情况下,我也不知道FLT_RADIX
在任何主流C编译器中是否会出现10.
我特别关注的是,我正在编写一个只能在通用计算机上运行的应用程序的代码,而且我想知道我是否可以在FLT_RADIX==2
没有严重关注的情况下静态断言,就像我目前静态断言一样!(unsigned char)256
.
我注意到在windows和linux x86上,float是4bytes,double是8,但long xins分别是x86和x86_64上的12和16.C99应该用特定的整体尺寸打破这种障碍.
最初的技术限制似乎是由于x86处理器无法处理超过80位的浮点运算(加上2个字节来进行舍入),但为什么标准与int类型相比不一致?他们为什么不至少达到80bit标准化?
阅读 C++17 草案 §6.9.1/5:
类型
char16_t
和char32_t
分别表示不同类型的具有相同的大小,符号性,和对准如uint_least16_t
和uint_least32_t
,分别在<cstdint>
被称为底层类型。
现在参考 C11 草案 §7.20.1.2/2,这是 C 库继承的参考:
typedef 名称
uint_leastN_t
指定宽度至少为N 的无符号整数类型,这样具有较小大小的无符号整数类型至少具有指定的宽度。因此,uint_least16_t
表示宽度至少为 16 位的无符号整数类型。
注意“至少”部分。这意味着char16_t
实际上可能有例如 32 位,从而形成char16_t
一个 UTF-16 原始数据的错误表示的数组。在这种情况下,将此类数组写入二进制文件将导致有效代码单元与 U+0000 字符交替。
是否有充分的理由char16_t
根据uint_least16_t
而不是来定义uint16_t
?或者它只是标准中的一个缺陷?
正如许多程序员都知道 C 中有几种浮点类型。到目前为止,我知道float
,double
但long double
我不太确定它们是全部,因为我发现了几个定义,例如__DEC32_MAX__
。起初我以为这是另一个名称,__FLT_MAX__
但当我尝试打印它时,我意识到它是不同的(如下所示):
#include <stdio.h>
void main(void)
{
__mingw_printf("flt value: %e, size: %d\n", __FLT_MAX__, sizeof(__FLT_MAX__));
__mingw_printf("dbl value: %e, size: %d\n", __DBL_MAX__, sizeof(__DBL_MAX__));
__mingw_printf("ldbl value: %e, size: %d\n", __LDBL_MAX__, sizeof(__LDBL_MAX__));
__mingw_printf("dec32 value: %e, size: %d\n", __DEC32_MAX__, sizeof(__DEC32_MAX__));
__mingw_printf("dec64 value: %e, size: %d\n", __DEC64_MAX__, sizeof(__DEC64_MAX__));
__mingw_printf("dec128 value: %e, size: %d\n", __DEC128_MAX__, sizeof(__DEC128_MAX__));
}
/* output:
flt value: 3.402823e+038, size: 4
dbl value: 1.797693e+308, size: 8
ldbl value: 3.237664e-317, size: 16
dec32 …
Run Code Online (Sandbox Code Playgroud) 前言:
我目前正在尝试解密旧的二进制格式(在日本80年代中期到80年代后期开发),该格式将浮点值存储在4字节块中,而不是用IEEE754标准转换.我有一个程序为我转换值,所以我可以操纵二进制文件来更改存储的值并查看结果,但我无法弄清楚如何解释它们.
我确实解释了4个字节的每个可能的排列作为IEEE浮点数,但没有一个是正确的,所以我可以说它不是字节序问题,也不是我知道或可以在互联网上找到的浮点数表示.
我试图调查我使用的程序的程序集,但是我的汇编程序技能不够好,无法从中获取任何东西.
这里有些例子:
Actuall问题:
在IEEE754标准之外/之前是否还有其他(旧的)32位浮点表示?
floating-point binaryfiles data-conversion binary-data ieee-754
在"C Primer Plus 5/e"一书中,我看到作者写道:
C标准规定浮子必须能够代表至少6个有效数字并且允许至少
10^(-37)
为 1的范围10^(+37)
.
但是为了这样做并同时使用自然大小,它将需要4个字节.所以事实上,人们的范围可以从10 ^( - 63)到10 ^(+ 63),参见
http://en.wikipedia.org/wiki/Floating_point#Internal_representation
所以我在脑海中提出了一个问题:为什么C标准选择范围的要求at least 10^(-37) to 10^(+37)
.当然,可能需要考虑计算速度.但除此之外,有没有理由不使用完整的32位空间?
在C中评估以下表达式时,输出为零而不是无穷大.但是根据C运算符优先级规则,输出应该是无穷大.
double a=1/(1.0/0.0);
printf("a : %.18le\n", a);
Run Code Online (Sandbox Code Playgroud)
请解释一下gcc编译器如何评估这个?
c ×7
c++ ×5
ieee-754 ×4
binaryfiles ×2
precision ×2
types ×2
architecture ×1
binary-data ×1
c11 ×1
c99 ×1
decimal ×1
double ×1
endianness ×1
processor ×1
standards ×1
unicode ×1
utf-16 ×1