I would like to know how to convert from an integer to a floating point value, without assigning to an intermediate variable. The code in question looks like this:
Format('Theoretical peak scaling %6.2f', [ThreadCount])
This obviously fails at runtime because ThreadCount
is an integer.
I tried the obvious
Format('Theoretical peak scaling %6.2f', [Double(ThreadCount)])
and the compiler rejects that with
E2089 Invalid typecast
I know I can write
Format('Theoretical peak scaling %6.2f', [ThreadCount*1.0])
but that reads poorly and will just tempt a future maintainer to remove the multiplication in error.
Does anyone know of a clean way to do this without an intermediate variable, and in way that makes the codes intent clear to future readers?
This maybe feels silly... but if it's an integer why not just :
Format('Theoretical peak scaling %3d.00', [ThreadCount]);
It's not like you're ever going to have anything but zeroes after the decimal point, right?
You have the alternative to use a record helper
for intrinsic types:
type
TIntHelper = record helper for Integer
function AsFloat : Double;
end;
function TIntHelper.AsFloat: Double;
begin
Result := Self;
end;
Format('Theoretical peak scaling %6.2f', [ThreadCount.AsFloat])
This was added in XE3, but with some restrictions from Embarcadero. Since only one helper can be in scope, Emarcadero suggests that this feature is for them to use inside the RTL only.
Quote from Marco Cantu:
we advise against writing your own (although you might want to do this as a temporary measure for types we don't support)
the reason is not just the one helper per class rule, but also that this behavior change in the future, with different compiler mechanism. so if you got for this, don't hold your breath for the future.
Reference: On Record/Class/Type Helpers
.
Update: In XE4
, a built-in helper class for integers, TIntegerHelper
, has a method ToDouble
.
Using RTTI
it can be solved like this with built in language elements:
Format('Theoretical peak scaling %6.2f',
[TValue.From<Integer>(ThreadCount).AsExtended])
Just FTR, a benchmark shows that Double(Variant(i))
and inlined helper i.AsFloat
are comparable, while TValue.From<Integer>(i).AsExtended
is 200+ times slower.
It's academic and I'd use a function or * 1.0 but this works
Format('Theoretical peak scaling %6.2f', [Double(Variant(ThreadCount))])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With