【问题标题】:simple question about assigning float to int关于将 float 分配给 int 的简单问题
【发布时间】:2010-09-13 22:52:10
【问题描述】:

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

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

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 行。为什么所有其他人都将浮点数转换为int(我假设正确的词是“casting”,如果我错了,请纠正我)将float转换为int,但在NSLog内部却没有发生。这是否与字符串格式%d 参数有关,并且它很挑剔(因为没有更好的词)?

【问题讨论】:

    标签: objective-c c


    【解决方案1】:

    你告诉 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);
    

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

    【讨论】:

      【解决方案2】:

      首先,您从未在程序中使用过floats。他们是doubles。

      其次,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

      【讨论】:

      • 如果你想节省空间,你可以使用浮点数而不是双精度数,通常用于大型数组(不是几个堆栈变量)。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        格式字符串%d 需要一个十进制数,表示以 10 为底的整数,而不是浮点数。你想要的是%f,如果你想让它打印出来8.0

        【讨论】:

        • 是的。 %d 表示“十进制”,而不是“双倍”。
        • %g,在固定十进制和科学格式之间智能选择。
        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-05
          • 1970-01-01
          • 2018-02-23
          • 2021-12-11
          • 1970-01-01
          • 1970-01-01
          • 2013-10-15
          • 1970-01-01
          相关资源
          最近更新 更多