Question

I want to return the Fractional part of a number as an Integer value.

How can I do it?

For example I have 12.98 and I want to return 98 in an Integer variable.

Was it helpful?

Solution

try this

function FractionToInt(const Precision:Integer; const Amount: Double): Integer;
begin
  Result := Trunc(Frac(Amount) * Power(10, Precision));
end;

OTHER TIPS

The standard function Frac returns the fractional part of the number.

This function returns the value as a floating point value. You want the fractional part as an integer, using a decimal representation. But that's just not possible. Or at least will not do what you expect.

For example, what would you expect for 0.1? Well it turns out that 0.1 cannot be represented exactly in binary floating point: http://pages.cs.wisc.edu/~rkennedy/exact-float?number=0.1

As another example, in double precision, your value of 12.98 is actually represented as

12.98000 00000 00000 42632 56414 56060 11152 26745 60546 875

which I am sure is not what you are expecting. So what you are asking for will, if interpreted at face value, not behave as you would expect. I think you will need to take a little time to come to terms with this issue of representability. Required reading: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

If you want to work with fractional values with decimal representation, you need to use a decimal rather than binary data type. In Delphi that would typically mean using the Currency data type which is a fixed point decimal data type.

This will work up to 10 Decimal places

you will need to include math in the uses clause

function GetFractionValueAsInteger( Value : Double ) : Integer;
var fFracValue : Double;
    iFracLength : integer;
begin
  result := 0;
  fFracValue := Frac( value );
  if fFracValue > 0 then
    fFracValue := SimpleRoundTo( fFracValue + 0.00000000001, -10)
  else if fFracValue < 0 then
    fFracValue := SimpleRoundTo( fFracValue - 0.00000000001, -10);
  if fFracValue = 0 then
    exit;
  if fFracValue < 0 then
    iFracLength := Length(Floattostr( fFracValue ))-3
  else
    iFracLength := Length(Floattostr( fFracValue ))-2;
  if iFracLength <= 0 then
    exit;
  result := Round( fFracValue * Power( 10,  iFracLength));
end;

Example of using this

ShowMessage( inttostr( GetFractionValueAsInteger( 12.98 ) ) );         //=98
ShowMessage( inttostr( GetFractionValueAsInteger( 12.9 ) ) );          //=9
ShowMessage( inttostr( GetFractionValueAsInteger( 12.000 ) ) );        //=0
ShowMessage( inttostr( GetFractionValueAsInteger( - 10.333 ) ) );      //=-333
ShowMessage( inttostr( GetFractionValueAsInteger( 33.33 ) ) );         //=33
ShowMessage( inttostr( GetFractionValueAsInteger( 33.000333 ) ) );     //=333
ShowMessage( inttostr( GetFractionValueAsInteger( 33.1023456789 ) ) ); //=1023456789

i have included SimpleRoundTo because sometimes getting the Frac value of 3.33 can return something like 0.332999999999998

You can do this way:

const
  DECIMALS = 2;
var
  I: Real;
  Inte: Integer;
begin

  I := 12.98;
  Inte := StrToInt(Copy(FloatToStr(Frac(I)*100),1,DECIMALS));
  ShowMessage(IntToStr(Inte));

end;

You need define your constant of decimals. Isn't the best solution, but i hope help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top