Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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_Compiler Warnings_Precision - Fatal编程技术网

C 什么是;较宽范围内的精度较低”;警告到底是什么意思?

C 什么是;较宽范围内的精度较低”;警告到底是什么意思?,c,compiler-warnings,precision,C,Compiler Warnings,Precision,我有以下代码,用于int为16位、long int为32位的嵌入式平台: #define MULTIPLIER 0x1000 static void my_function(uint16_t i, void *p) { uint32_t start = MULTIPLIER * i; ... } 我的编译器向我发出警告: Warning 1 : lower precision in wider context: '*' 这一行 这到底意味着什么?我可以通过将#define改

我有以下代码,用于int为16位、long int为32位的嵌入式平台:

#define MULTIPLIER 0x1000

static void my_function(uint16_t i, void *p)
{
    uint32_t start = MULTIPLIER * i;
    ...
}
我的编译器向我发出警告:

Warning 1 : lower precision in wider context: '*'
这一行

这到底意味着什么?我可以通过将#define改为

#define MULTIPLER 0x1000ul

(明确地将其设为无符号长)但我想理解警告

我认为该警告意味着您可能需要一个32位的结果,但由于
0x1000
具有type
int
I
具有type
int16\t
,表达式仅为type
int
,可能会溢出,而不会给出所需的结果。

我认为警告意味着您可能需要32位结果,但由于
0x1000
具有type
int
I
具有type
int16\u t
,因此,表达式仅为
int
类型,可能会溢出,无法提供所需的结果。

它警告您,乘法将使用16位值进行,然后16位结果将转换为32位结果。这可能不是您所期望的(16位乘法可能会溢出),因此发出警告


涵盖该问题

它警告您,乘法将使用16位值进行,然后16位结果将转换为32位结果。这可能不是您所期望的(16位乘法可能会溢出),因此发出警告


涵盖表达式
乘数*i
的问题编译器从操作数类型中选择精度更高的类型。在第一种情况下,您给它两个
int
s,这意味着您将得到一个截断的结果,之后将转换为
long int
,但精度仍然是16位


在后一种情况下,显式地使一个操作数变长,然后将结果写入相同精度的变量

对于表达式
乘数*i
,编译器从操作数类型中选择精度更高的类型。在第一种情况下,您给它两个
int
s,这意味着您将得到一个截断的结果,之后将转换为
long int
,但精度仍然是16位


在后一种情况下,显式地使一个操作数变长,然后将结果写入相同精度的变量

虽然这听起来似乎有道理,但我相信你错了。我非常确定乘法是在32位寄存器(在i386上)中完成的,而不考虑16位声明。结果将放置在32位目标中,因此不会截断。我认为问题在于签名与未签名的冲突,但我必须查看asm代码才能确定。PS:我不认为这是一个溢出警告,因为这是一个运行时的事情。16位*16位可能溢出,也可能不溢出,这取决于操作数值。@Hotei:你错了,原因有很多。(1) 这不是i386,而是一些未指定的16位嵌入式环境。在这种情况下,C需要将结果截断为16位。我对Macintosh C编译器的一个主要不满是,尽管68000只有一条16x16->32乘法指令,在C语言中没有编写16x16->32乘法的好方法。编译器会不遗余力地截断乘法指令的结果,除非其中一个操作数被强制转换为long,在这种情况下,它会浪费时间进行long*long乘法。在8位嵌入式系统上,我有时使用自己的乘法和除法例程;我最喜欢的是ldivmod,它将一个全局long除以一个8位值,得到一个8位结果。@R..:我想说的是,C(IIRC)将操作数转换为其最宽的操作数,即16位*32位将以32位精度完成。如果我们假设C是“最近”实现,那么#define MULTIPLIER 0x1000将被解释为int,ie 32位签名。将无符号16位和有符号32位的结果填充到无符号32位中将是(未定义的),这是编译器试图针对公认的模糊错误消息提出的建议。就像我说的,我需要看看asm,看看这是否真的发生了。实施方式差别很大。@Hotei:请重新阅读问题
int
在这个平台上是16位的,所以两个操作数都是16位的。虽然这听起来似乎有道理,但我相信你错了。我非常确定乘法是在32位寄存器(在i386上)中完成的,而不考虑16位声明。结果将放置在32位目标中,因此不会截断。我认为问题在于签名与未签名的冲突,但我必须查看asm代码才能确定。PS:我不认为这是一个溢出警告,因为这是一个运行时的事情。16位*16位可能溢出,也可能不溢出,这取决于操作数值。@Hotei:你错了,原因有很多。(1) 这不是i386,而是一些未指定的16位嵌入式环境。在这种情况下,C需要将结果截断为16位。我对Macintosh C编译器的一个主要不满是,尽管68000只有一条16x16->32乘法指令,在C语言中没有编写16x16->32乘法的好方法。编译器会不遗余力地截断乘法指令的结果,除非其中一个操作数被强制转换为long,在这种情况下,它会浪费时间进行long*long乘法。在8位嵌入式系统上,我有时使用自己的乘法和除法例程;我最喜欢的是ldivmod,它将一个全局long除以一个8位值,得到一个8位结果。@R..:我想说的是,C(IIRC)将操作数转换为其最宽的操作数,即16位*32位将以32位精度完成。如果我们假设C是“最近”实现,那么#define MULTIPLIER 0x1000将被解释为int,ie 32位签名。将无符号16位和有符号32位的结果填充到无符号32位将是(未定义的),这是编译器正在尝试的