关于将float赋值给int的简单问题

时间:2010-09-13 22:52:10

标签: objective-c c

这可能是非常简单的事情,但我没有得到我期待的结果。如果这是一个愚蠢的问题,我道歉,我只是不知道谷歌的用途。

最简单的解释方法是使用一些代码:

int var = 2.0*4.0;

NSLog(@"%d", 2.0*4.0);//1
NSLog(@"%d", var);//2

if ((2.0*4.0)!=0) {//3
    NSLog(@"true");
}

if (var!=0) {//4
    NSLog(@"true");
}

这会产生以下输出:

0   //1
8   //2
true    //3
true    //4

我不理解的是行//1。为什么所有其他人都在转换(我假设正确的单词是“cast”,请纠正我,如果我错了)浮动到一个int,但在NSLog内部它没有发生。这是否与字符串格式%d参数有关,而且它很繁琐(缺少更好的单词)?

5 个答案:

答案 0 :(得分:4)

你告诉NSLog你传递了一个带有@"%d"格式说明符的整数,但你实际上并没有给它一个整数;你给它一个双精度浮点值(8.0,当它发生)。当你骗到NSLog时,它的行为是未定义的,你会得到意想不到的结果。

不要欺骗NSLog。如果要在打印前将2.0*4.0的结果转换为整数,则需要明确地执行此操作:

NSLog(@"%d", (int)(2.0*4.0));

相反,如果要将2.0*4.0的结果打印为双精度浮点数,则需要使用不同的格式说明符:

NSLog(@"%g", 2.0*4.0);

更广泛地说,任何采用可变数量的参数和一些格式字符串的函数都可以告诉它如何解释它们。您可以确保传递的数据与相应的格式说明符相匹配;隐式转换不会发生在您身上。

答案 1 :(得分:3)

首先,您从未在程序中使用float。他们是double

其次,NSLogprintf等论据不会自动转换为您使用%d%f指定的内容。它遵循无类型参数的标准提升规则。见the ISO specification, sec 6.5.2.2.6 and 6.5.2.2.7。注意这些函数中的超奇怪规则,

  • float会自动提升为double
  • ,任何小于int的整数都会提升为int。 (见6.3.1.1.2)

因此,严格来说,规范%f并未显示float,而是显示double。参见同一文件,Sec。 7.19.6.1.8。

另请注意,在您的案例1和3中,促销活动是double

答案 2 :(得分:2)

在示例2,3和4中,float被分配​​给int(转换它)或者与int(它也转换它)进行比较。但是,在1中,您将float作为参数传递给函数。 printf函数允许初始格式字符串之后的所有参数都是任何类型,因此这是有效的。但是因为编译器不知道你的意思是它是一个int(记住,你还没有做任何让编译器知道的事情),所以float作为一个浮点值传递。当printf看到%d格式化说明符时,它会从参数列表中为int弹出足够的字节,并将这些字节解释为int。这些字节看起来像一个整数0。

答案 3 :(得分:0)

格式字符串%d需要十进制数,表示基数为10的整数,而不是浮点数。如果你想要打印%f

,你想要的是8.0

答案 4 :(得分:0)

NSLog的第一个参数是格式字符串,然后第二个(和后续)参数可以是任何类型。编译器不知道编译时应该是什么类型,因此不会尝试将它们转换为任何类型。在运行时,NSLog假定第二个(和后续)参数是格式字符串中指定的。如果出现意外不匹配的情况,通常会发生不愉快的事情。

概要;确保在第二个(及后续)参数中传递正确类型的变量。