当前位置: 首页 > 编程语言 > C#

int转float的问题分享

时间:2023-04-10 13:43:52 C#

int转float的问题有一个奇怪的行为,我无法理解。同意浮点数是近似值,因此即使显然返回没有小数的数字的操作也可以近似为带小数的数字。我这样做:intnum=(int)(195.95F*100);因为它是浮点运算,所以我得到19594而不是19595..但它是正确的。令我困惑的是,如果我这样做floatflo=195.95F*100;intnum=(int)flo;我得到了19595的正确结果。知道为什么会这样吗?我看看这是不是编译器在做数学运算,但即使你强迫它,它也会这样表现:staticvoidMain(){inti=(int)(GetF()*GetI());//19594floatf=GetF()*GetI();intj=(int)f;//19595}[MethodImpl(MethodImplOptions.NoInlining)]staticintGetI(){return100;}[MethodImpl(MethodImplOptions.NoInlining)]staticfloatGetF(){return195.95F;它是保存在寄存器中(比正常的r4更宽)还是强制转换为浮点变量看起来不同:L_0001:callfloat32Program::GetF()L_0006:callint32Program::GetI()L_000b:conv.r4L_000c:mulL_000d:conv.i4L_000e:stloc.0VSL_000f:调用float32Program::GetF()L_0014:调用int32Program::GetI()L_0019:conv.r4L_001a:mulL_001b:stloc.1L_001c:ldloc。1L_001d:conv.i4L_001e:stloc.2唯一的区别是stloc.1/ldloc.1。如果您进行优化构建(这将删除局部变量),我会得到相同的答案(19594),这一事实支持了这一点。这段代码...namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){floatresult=195.95F*100;intintresult=(int)(195.95F*100);}}}给出这个IL.methodprivatehidebysigstaticvoidMain(string[]args)cilmanaged{.entrypoint//Codesize14(0xe).maxstack1.localsinit([0]float32result,[1]int32intresult)IL_0000:nopIL_0001:ldc。r419595.IL_0006:stloc.0IL_0007:ldc.i40x4c8aIL_000c:stloc.1IL_000d:ret}//方法结束Program::Main查看IL_00001->compierhasdonecalculations..否则有十进制->二进制转换问题Mark的回答是正确的,因为它是nativefloat和float32/float64之间的转换。这包含在CLRECMA规范中,但DavidNotario对此的解释超出了我的能力范围。在第二个示例中,尝试将float转换为double:doubleflo=195.95F*100;intnum=(int)flo;我猜你的第一个例子是编译器使用double来保存中间结果,所以在float情况下你会失去精度。当你乘以100时,它是一个整数,所以它会在那一步进行隐式转换。如果你把“F”放在100之后,我敢打赌它们会是一样的。当它是引用类型时,我通常使用括号装箱/拆箱。当它是值类型时,我尝试使用Convert静态方法。试试Convert.ToSingle(YourNumber);以获得更可靠的转换。HTH我无法回答为什么第二个有效而第一个无效。但是,我可以告诉你,195.95在二进制中是一个不终止的小数,所以像这样的舍入错误是不可避免的。尝试转换为double而不是float。您还可以使用货币或小数类型代替浮点数。这将以不同方式更准确地存储数字。关于浮点数和IEEE表示的更多信息,请访问:http://en.wikipedia.org/wiki/IEEE_754以上就是C#学习教程的全部内容:从int到float的转换。有用,需要了解更多C#学习教程,希望大家多多关注—本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: