我知道C和C ++标准留下了语言实现的许多方面 - 仅仅因为如果存在具有其他特征的体系结构,那么为它编写符合标准的编译器是非常困难或不可能的。
我知道40年前任何电脑都有自己独特的规格。但是,我不知道今天使用的任何架构:
CHAR_BIT != 8
signed
不是两个补充(我听说Java有这个问题)。我问的原因是我经常向人们解释,C ++不要求任何其他低级方面,如固定大小的类型†。这很好,因为与其他语言不同,它使你的代码在正确使用时可以移植(编辑:因为它可以移植到更多架构而不需要模拟机器的低级方面,例如符号+幅度架构上的二进制补码算法) 。但我感到很难过,我自己也无法指出任何特定的架构。
所以问题是:哪些架构具有上述属性?
†uint*_t
是可选的。
答案 0 :(得分:105)
看一下这个
Unisys ClearPath Dorado Servers
为尚未迁移所有Univac软件的用户提供向后兼容性。
关键点:
CHAR_BIT == 9
不知道他们是否提供了C ++编译器,但他们可以。
现在,他们的C手册的最新版本的链接浮出水面:
Unisys C Compiler Programming Reference Manual
第4.5节有一个包含9,18,36和72位的数据类型表。
答案 1 :(得分:47)
您对大型机的假设都不适用。首先,我不知道
使用IEEE 754的大型机:IBM使用base 16浮点,和
两个Unisys大型机都使用基础8.Unisys机器有点
在许多其他方面都很特别:Bo提到了2200架构,
但MPS架构甚至更奇怪:48位标记的单词。
(该字是否为指针取决于该字中的一位。)
并且数字表示被设计为没有真实的
浮点和积分算术之间的区别:浮动
点是基数8;它不需要标准化,而且不像每一个
我见过的其他浮点数,它将小数点放在右边
尾数,而不是左边,并使用有符号的幅度
指数(除了尾数)。随着结果,一个
积分浮点值具有(或可以具有)完全相同的位
表示为带符号的整数。而且没有浮动
点算术指令:如果两个值的指数是
两者都是0,指令执行积分运算,否则执行
浮点运算。 (标记哲学的延续
体系结构。)这意味着虽然int
可能占用48位,8
它们必须为0,否则该值不会被视为整数。
答案 2 :(得分:39)
完全符合IEEE 754标准在浮点实现中很少见。在这方面削弱规范可以进行大量优化。
例如,subnorm支持x87和SSE之间的差异。
融合在源代码中单独的乘法和加法的优化也会稍微改变结果,但在某些架构上是很好的优化。
或者在x86严格的IEEE合规性上可能需要设置某些标志或浮点寄存器和普通内存之间的额外传输以强制它使用指定的浮点类型而不是其内部80位浮点数。
有些平台根本没有硬件浮动,因此需要在软件中模拟它们。并且IEEE 754的一些要求在软件中实现可能是昂贵的。特别是舍入规则可能是个问题。
我的结论是,如果您不总是希望保证严格的IEEE合规性,那么您不需要异国情调的架构。因此,很少有编程语言可以保证严格的IEEE合规性。
答案 3 :(得分:39)
我发现this link listing some systems位于CHAR_BIT != 8
。它们包括
某些TI DSP具有
CHAR_BIT == 16
BlueCore-5芯片(蓝牙 来自Cambridge Silicon Radio的芯片,有
CHAR_BIT == 16
。
当然,Stack Overflow上有一个问题:What platforms have something other than 8-bit char
对于非二进制补语系统, comp.lang.c++.moderated有一个有趣的读物。总结:有些平台具有补码或符号和幅度表示。
答案 4 :(得分:22)
我很确定VAX系统仍在使用中。它们不支持IEEE浮点数;他们使用自己的格式。 Alpha支持VAX和IEEE浮点格式。
Cray矢量机,如T90,也有自己的浮点格式,不过新的Cray系统使用IEEE。 (我使用的T90几年前退役了;我不知道是否有任何仍在使用中。)
T90还有一些有趣的表示指针和整数。本地地址只能指向64位字。 C和C ++编译器有CHAR_BIT == 8(必要因为它运行Unicos,一种Unix的风格,并且必须与其他系统互操作),但是本机地址只能指向64位字。所有字节级操作都由编译器合成,void*
或char*
在字的高3位中存储了一个字节偏移量。我认为一些整数类型有填充位。
IBM大型机是另一个例子。
另一方面,这些特定系统不一定必须排除对语言标准的更改。 Cray没有表现出将C编译器升级到C99的特别兴趣;大概是同样适用于C ++编译器的东西。 可能可能合理地收紧托管实现的要求,例如要求CHAR_BIT == 8,IEEE格式浮点(如果不是完整语义)和2的补码而没有填充位用于有符号整数。旧系统可以继续支持早期的语言标准(当C99出现时C90没有死亡),并且对于诸如DSP的独立实现(嵌入式系统),要求可能更宽松。
另一方面,未来系统可能有充分理由做出今天被认为是异国情调的事情。
答案 5 :(得分:14)
根据 gcc 源代码:
对于 1750a , dsp16xx 架构, CHAR_BIT
为16
位。
dsp56k 架构的CHAR_BIT
为24
位
c4x 架构CHAR_BIT
为32
位。
您可以通过以下方式轻松找到更多信息:
find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"
或
find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"
如果CHAR_TYPE_SIZE
被恰当地定义。
如果目标架构不支持浮点指令, gcc 可能会生成软件回退,默认情况下不符合标准。除此之外,还可以使用特殊选项(如-funsafe-math-optimizations
还禁用零保留符号)。
答案 6 :(得分:7)
我想补充一点,这与OP问题更相关:10-15年前人们做什么,当GPU浮点数不是IEEE时,以及当时没有API,如今天的OpenCL或CUDA程序GPU?信不信由你,早期的GPU计算先驱设法编程GPU而没有API来做!我在公司遇到了其中一个。这就是他所做的:他将计算所需的数据编码为图像,其中像素表示他正在处理的值,然后使用OpenGL执行他需要的操作(例如“高斯模糊”来表示具有正态分布的卷积等),并将得到的图像解码回结果数组。这仍然比使用CPU更快!
这样的事情促使NVidia最终使其内部数据二进制与IEEE兼容,并引入了面向计算而非图像处理的API。