Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将浮点转换为非标准编码_C++_C_Cocoa_Math_Types - Fatal编程技术网

C++ 如何将浮点转换为非标准编码

C++ 如何将浮点转换为非标准编码,c++,c,cocoa,math,types,C++,C,Cocoa,Math,Types,我正在写一个创建ICC颜色格式的程序。这些格式指定名为s15Fixed16Number的数据类型,该数据类型具有符号位、15个整数位和16个小数位。IEEE 754 32位浮点有一个符号位、8个指数位和23个分数位 我需要从文本框中获取输入,并将其转换为S15Fixed16数字。谷歌图书上出现了一些搜索,但这是关于将十进制数转换为s15fixed16的问题。我想我可以使用链接中解释的方法,但是我还没有做任何测试来确定它的准确性。我想我也可以尝试转换文本框中的字符输入,但我还没有考虑太多 我用的是

我正在写一个创建ICC颜色格式的程序。这些格式指定名为s15Fixed16Number的数据类型,该数据类型具有符号位、15个整数位和16个小数位。IEEE 754 32位浮点有一个符号位、8个指数位和23个分数位

我需要从文本框中获取输入,并将其转换为S15Fixed16数字。谷歌图书上出现了一些搜索,但这是关于将十进制数转换为s15fixed16的问题。我想我可以使用链接中解释的方法,但是我还没有做任何测试来确定它的准确性。我想我也可以尝试转换文本框中的字符输入,但我还没有考虑太多

我用的是可可粉,但我认为这无关紧要;任何C函数都应该工作。以下是S15Fixed16数字格式的一些示例值:

              -32768.0 = 0x80000000
                     0 = 0x00000000
                   1.0 = 0x00010000
 32767 + (65535/65536) = 0x7FFFFFFF

我想已经有一段时间没有上数值计算课了

不要对浮点数的内部表示法感到兴奋。定点值只是整数,具有恒定的比例因子。请记住,浮点数的精度比目标格式的精度更有限,因此对于较大的值,预期值可能在较低的9位处关闭

//s15Fixed16Number is presumably typedef'ed to unsigned int
float foo = 1.0f;
int fooFixedSigned = (int)(foo * 65536);
s15Fixed16Number fooFixed = (s15Fixed16Number)(abs(fooFixedSigned));
if (foo < 0) fooFixed = fooFixed | (1 << 31);
//you'll also need to explicitly check for overflows and underflows and handle them however is appropriate to your situation
//s15Fixed16Number可能是typedef'ed为unsigned int
浮球foo=1.0f;
int fooFixedSigned=(int)(foo*65536);
s15Fixed16Number fooFixed=(s15Fixed16Number)(abs(fooFixedSigned));

如果(foo<0)foosfixed=foosfixed |(1假设您的C环境执行2的补码整数,那么这比看起来要简单得多

typedef long s1516;  // 32bit 2's complement signed integer
s1516 floattos1516(double f) {
    return (s1516)(f * 65536. + 0.5);
}
表示法是一个16位小数的定点值。这与分母始终为65536(或216)的有理数相同。要从浮点值形成这样一个有理数,只需乘以分母。然后只需适当的舍入和整数类型的截断

标准选择了他们所使用的形式,因为如果系统使用2的补码整数算法,这种方法就可以工作。虽然最左边的位确实表示符号,但它不是浮点表示中使用的符号位

如果您的计算是真正的
float
而不是
double
,您会发现您的计算精度不如接近满刻度的数字的定点值。如果您使用
double
进行计算,那么您的计算精度将始终高于结果。

编辑:

显然是最新的规范为规范ICC.1:2004-10(配置文件版本4.2.0.0)。第5.1.3节:

5.1.3 S15固定编号16

一种固定的有符号4字节/32位数量,具有 16个小数位,如表3所示

表3-S15Fixed16编号 数字编码 -32768,0 80000000小时 百万小时 1,0 000100000h 32767+(65535/65536)7FFFFFH 除了对小数点表示法的局部偏好外,这些值完全符合我的理解,即表示法只是有符号2的补码整数,应该除以65536才能得到它们的值

表示法的自然转换是简单地乘以65536,再从中简单地除以。选择合适的舍入规则是一个优先选择的问题

满刻度范围从-32768.0(0x8000000)到大约32767.9999847412(0x7fffffff),包括在内


我同意,如果规范碰巧显示了任何负值的十六进制表示形式,那就更清楚了。我浏览了整个文档,发现仅有的十进制和十六进制表示的值是CIE XYZ色度坐标,根据定义,它的范围是0到1,因此作为示例负值没有帮助值。

如Alan所示,通过乘以或除以单位值,可以将定点值转换为浮点值,也可以将浮点值转换为浮点值。这种格式通过指定符号位带来了一点小小的变化。您应该使用
long
而不是
int
——前者至少有32位,而后者仅保证为have 16.抱歉,没有。关闭,但是没有。表示法明确表示它是2的补码。你不能通过获取绝对值得到它。此外,你尝试使用位智能AND运算符设置符号位将清除除符号位以外的所有位。原始问题指定了显式符号位,而不是2的补码。但是你是right关于不正确的按位运算符,这是一个错误。问题有点像,但它引用的规范没有,而且样本值显然不是有符号的大小。问题误解了规范。此外,如果您想转换为有符号的大小形式,那么您可能还需要保证在多重类型中溢出ply没有为超出范围的正数设置符号位。如果示例转换正确,则s15Fixed16Number没有符号位:-它只是一个标准的两位补码有符号编码。例如,-32768.0=0x8000000表示:-1.0=0xFFFF0000这由声称为s15Fixed16的ICC配置文件格式规范备份数字:“这种类型表示一个固定的有符号4字节/32位的量,它有16个小数位。”。它并没有说它有符号位,而是说这个数字是有符号的。标准只给出一个(伪造的)编码为s15Fix16Number的负数示例,值-32768.9999。这显然超出了有效范围。不清楚-1应编码为什么;不清楚最小有效编码值是(-32768.00000或-32767.9999)。附录标题中使用的类型是:
typedef long icS15Fixed16Number;
@Jonathon,我看不到您在 Table 3 — s15Fixed16Number Number Encoding -32768,0 80000000h 0 00000000h 1,0 00010000h 32767 + (65535/65536) 7FFFFFFFh