如何在Delphi中将整数转换为浮点数?

10
如何在Delphi中将整数转换为浮点数?
例如:int_h := int_var / 1.5 * int_var;

2
只是分配它不起作用吗? - Uli Gerhardt
是的,赋值应该可以工作,因为int隐式转换为浮点数。 - CodesInChaos
1
“h” 是以浮点数的形式输入的吗? - Larry Lustig
5个回答

12

i*1.0应该转换为浮点数。任何涉及任何类型的浮点数的计算都会隐式地转换为extendend,然后在赋值时隐式地转换为所需的结果类型。与C/C ++相比,所有计算都在Extended(80位浮点数,x87浮点单元的内部格式)中进行,并稍后转换回来。

real(i)也可能有效。


我想要反过来。 - Aftershock
1
我宁愿使用 i + 0.0 而不是 i * 1.0,因为即使一年级的学生也能够进行加法,但我认为只有到了二年级才开始学习乘法。(开个玩笑 - 乘法需要比加法更多的 CPU 或 FPU 动力) - Reversed Engineer

6

整数转浮点数

不需要进行类型转换,只需赋值即可。

Float1 := Integer1;

你的问题似乎是关于浮点数转整数。
两种选择:
Integer1 := Trunc(Float1); //truncate 

或者

Integer1 := Round(Float1); //Round

Trunc() 的相反操作实际上是 Ceil()。Trunc() 会朝向零的方向舍入,而 Ceil() 则会朝着正无穷大(如果是正数)或负无穷大(如果是负数)的方向舍入。 - Trinidad
3
向下取整函数 Floor 总是向负无穷方向舍入,而不会改变数值的小数部分。向上取整函数 Ceil 总是向正无穷方向舍入,也不会改变数值的小数部分。截断函数 Trunc 则总是将数值去掉小数部分并保留整数部分。因此,Ceil() 的相反函数不是 Trunc,而是 Floor。 - CodesInChaos

2

根据您所拥有的表达式类型,有3种可能的方法。

var
  Float: Double;
  Int1: Integer;
  Int2: Integer;
begin
  Int1 := 925;
  Int2 := 21;
  Float := Int1; // simple form: assign it
  Writeln(Float);
  Float := Int2 / Int1; // floating point division: assign it
  Writeln(Float);
  Float := (1.0 * Int2) * Int1; // integer operator: multiply by 1.0 and add parenthesis
  Writeln(Float);
end.

输出:

 9.25000000000000E+0002
 2.27027027027027E-0002
 1.94250000000000E+0004

3
先加一再减一;我希望得到双重动力:这有助于我写出更好的答案。 - Jeroen Wiert Pluimers

2

您可以做以下操作:

myFloat := myInteger;

该类型转换无效:E2089 无效的类型转换。 - Barry Kelly

1

我有这两个(我有更多,但是举例就足够了)重载函数:

interface
   function MyFunc(Value:Integer):Integer;overload;
   function MyFunc(Value:Double):Double;overload;
implementation
   function MyFunc(Value:Integer):Integer;
   begin
        MyFunc:=Math.Ceil( {Do some extra complicated Math calcs}
                          *
                           MyFunc( {¿How to Type Cast as Double?} Value )
                         );
   end; 
   function MyFunc(Value:Double):Double;
   begin
        MyFunc:={Do some Math calcs with Value};
   end; 

如何将整数转换为双精度浮点数? 我不喜欢使用´(1.0*Value)´或´(0.0+Value)´,因为它们使用的CPU时间较少,必须存在其他方法来完成此操作。
注意:我是指在该调用中进行类型转换!!! 注意:该调用是重载函数之一,其中一个调用了另一个。
希望有人能找到一种方法,因为将´MyFunc((Double)Value)´放入会显示无效的类型转换...为什么把整数强制转换为双精度浮点数不可能???双精度浮点数可以存储整数...并且当直接赋值时,它会直接进行强制转换...´MyVarOfTypeDouble:=MyvarOfTypeInteger;´非常完美。
问题出现在重载函数上...它不知道我想调用哪个双版本...这就是为什么需要进行强制转换的原因...
换句话说...这将像魅力一样工作:
interface
   function MyFunc_Integer(Value:Integer):Integer;
   function MyFunc_Double(Value:Double):Double;
implementation
   function MyFunc_Integer(Value:Integer):Integer;
   begin
        MyFunc_Integer:=Math.Ceil( {Do some extra complicated Math calcs}
                                  *
                                   MyFunc_Double(Value)
                                  );
   end; 
   function MyFunc_Double(Value:Double):Double;
   begin
        MyFunc_Double:={Do some Math calcs with Value};
   end; 

看,如果函数名不同,就不需要进行强制转换... 直到我找到更好的解决方案,我必须担心我将使用´(0.0+Value)´,其中应该可以使用(但实际不能)´(Double)value´,其中Value是Integer类型。

所以我的回答是... 不要放置代码´(Double)SomethingOfTypeInteger´(应该可以工作,但编译器不喜欢),而是放置另一个代码´(0.0+SomethingOfTypeInteger)´,我建议不要使用´(1.0*SomethingOfTypeInteger)´,因为它效率要低得多...

永远不要考虑创建这样的函数(它也比1.0*Value更糟糕):

function ConvetIntegerToDouble(Value:Integer):Double;
begin
     ConvetIntegerToDouble:=Value;
end;

那个函数很好,但是比直接写“0.0+value”要花费更多的时间。
现在对于非常非常聪明的人来说,他们会看到这段(非常丑陋的)代码:
    interface
       function MyFunc(Value:Integer):Integer;overload;
       function MyFunc(Value:Real48):Real48;overload;
       function MyFunc(Value:Real):Real;overload;
       function MyFunc(Value:Double):Double;overload;
       procedure CanYouGuess;
    implementation
    var
       MyVarOfTypeDouble:Double;
       function MyFunc(Value:Integer):Integer;
       begin
            MyFunc:=Round(MyFunc(1.0+Value));
       end;
       function MyFunc(Value:Real48):Real48;
       begin
            MyFunc:=MyFunc(2.0+Value);
       end;
       function MyFunc(Value:Real):Real;
       begin
            MyFunc:=MyFunc(4.0+Value);
       end;
       function MyFunc(Value:Double):Double;
       begin
            MyFunc:=(8.0+Value);
       end;
       procedure CanYouGuess;
       var
          MyVarOfTypeReal48:Real48;
          MyVarOfTypeReal:Real;
       begin
            MyVarOfTypeDouble:=MyFunc( 0 ); // What value will be on MyVarOfTypeDouble?
            MyVarOfTypeReal48:=0;
            MyVarOfTypeDouble:=MyFunc(MyVarOfTypeReal48); // What value will be on MyVarOfTypeDouble?
            MyVarOfTypeReal:=0;
            MyVarOfTypeDouble:=MyFunc(MyVarOfTypeReal); // What value will be on MyVarOfTypeDouble?
            MyVarOfTypeDouble:=MyFunc(0.0); // What value will be on MyVarOfTypeDouble?
       end;

现在尝试猜测数值...阅读代码并不清楚必须调用哪些函数...我传递一个整数,然后在Integer重载版本内...哪个被调用了...Real48重载版本还是Real或Double?...传递Real48和传递Real也是同样的情况...编译器完全没有发现错误...但我不知道哪个(如果只有一个)会被调用...当然不需要跟踪!!!你能吗?
对于这种情况,显式转换将非常有用...
请注意,我放置了1.0+、2.0+、4.0+、8.0+等2的幂...因此可以看到任何或某些它们的总和...如果结果为15...所有它们都必须运行...如果是3只有1.0和2.0,等等...二进制模式!!!像位权重等一样...这只是展示代码如何变得过于复杂...只因为重载函数必须具有不同的参数...
这是不允许的,因为编译器不知道该调用哪个:
    interface
       function MyFunc(Value:Double):Integer;overload;
       function MyFunc(Value:Double):Real48;overload;
       function MyFunc(Value:Double):Real;overload;
       function MyFunc(Value:Double):Double;overload;

是的,编译器有时候很傻... 只有在MyFunc用于赋值的情况下才能编译.... 请看以下代码:

MyVarOfTypeReal48:=MyFunc(1); // It can know return value must be Real48, so call that one... but compiler is not so Intelligent

在这种情况下,可以知道应该打哪个电话......问题出在:
MyVarOfTypeInteger:=Round(5*MyFunc(1)+MyFunc(2)*1.3); // This is problematic, first one could be understod as Integer version, second one as ... as what? Real, Real48 or Double? not possible to know... that is why compiler does not like such overloaded (with same arguments).

希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接