Dear Sir,

Please find the attached document for your reference. Could you tell me what is wrong of my answer?

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
        balance, posNeg, positive, negative: integer;

begin
    randomize;
    writeln('Get average balance');
    balance:=random(10000);
    posNeg:=random(2);
    if posNeg=0 then
      begin
        balance:=balance*-1-30;
      end
      else
        begin
          writeln('Positive balance.');
          balance:=balance*1.03;
        end;
      writeln('Your balance is ', balance);
      readln;
end.

Cheers,

Dani AI

Generated

Short answer: the problem is the data type. was right that using an integer for balance loses any fractional part when you do percentage math. Assigning a floating result into an integer truncates cents, so a 3% increase will silently drop the decimal part.

A bit more detail that clarifies the choices and why they matter:

  • Integer stores whole numbers only. Any fractional result assigned back to an integer is truncated (you lose cents).
  • Floating types (Real/Double) store fractional values but use binary floating-point, which can introduce tiny rounding errors (not ideal for precise money math).
  • Currency (Delphi) or storing values as integer cents are better for money: Currency is a fixed-point 64-bit type with four decimal places, and integer-cents gives exact two-decimal control.

Practical fixes and tips:

  1. Pick Currency for monetary calculations, or keep everything in integer cents (do all math on cents). That avoids binary rounding surprises.
  2. When generating a random balance, produce integer cents and convert to a Currency or divide by 100. This guarantees exact two-decimal values.
  3. When applying interest, compute the incremental cents and use Round (or integer math) so you do not silently truncate.
  4. Format output for display (two decimals) but remember formatting only affects presentation, not the stored numeric value.

Example (concept only — not a repeat of posted code):

var
  cents: Int64;
  bal: Currency;
begin
  Randomize;
  cents := Random(1000000);    // 0..999999 cents -> $0.00..$9999.99
  bal := cents / 100;          // exact currency value
  Writeln(FormatFloat('0.00', bal));
end;

This follows the spirit of 's interest explanation while avoiding loss of cents in 's original snippet.

Recommended Answers

All 6 Replies

Your main problem is 'balance' should be a real type, as multiplying it by 1.03 will return a non integer value. Here's how I'd do it:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  posNeg: integer;
  balance: Real; // balance must be a real type (supports decimal places)

begin
  try
    Randomize;
    Writeln('Get average balance');
    posNeg:=random(2);
    // Set posNeg to 1 or -1
    if posNeg = 0 then
      posNeg:=-1
    else
      posNeg:=1;
    // %.2f limits the float to 2 decimal places
    balance:=StrToFloat(Format('%.2f',[posNeg*(random+random(10000))]));
    Writeln('Average balance is '+FloatToStr(balance));
    if posNeg = -1 then
    begin
      Writeln('Negative balance.');
      balance:=balance-20;
    end else
    begin
      Writeln('Positive balance.');
      balance:=balance*1.03;
    end;
    // Format to 2 decimal places
    Writeln('Your new balance is ', Format('%.2f',[balance]));
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

Hope that helps.

Sub Xero

Hi,

Thank you for your kind reply and answer. Can I do at the following way?

program Hoard_It;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
        balance: real;
        posNeg, positive, negative: integer;

begin
    randomize;
    writeln('Get average balance');
    balance:=random(10000);
    posNeg:=random(2);
    if posNeg=0 then
      begin
        balance:=balance*-1-30;
      end
      else
        begin
          writeln('Positive balance.');
          balance:=balance*1.03;
        end;
      writeln('Your balance is ', balance:6:2);
      readln;
end.

Your main problem is 'balance' should be a real type, as multiplying it by 1.03 will return a non integer value. Here's how I'd do it:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  posNeg: integer;
  balance: Real; // balance must be a real type (supports decimal places)

begin
  try
    Randomize;
    Writeln('Get average balance');
    posNeg:=random(2);
    // Set posNeg to 1 or -1
    if posNeg = 0 then
      posNeg:=-1
    else
      posNeg:=1;
    // %.2f limits the float to 2 decimal places
    balance:=StrToFloat(Format('%.2f',[posNeg*(random+random(10000))]));
    Writeln('Average balance is '+FloatToStr(balance));
    if posNeg = -1 then
    begin
      Writeln('Negative balance.');
      balance:=balance-20;
    end else
    begin
      Writeln('Positive balance.');
      balance:=balance*1.03;
    end;
    // Format to 2 decimal places
    Writeln('Your new balance is ', Format('%.2f',[balance]));
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

Hope that helps.

Sub Xero

Hi,

Could you tell me what about the different between 'integer' and 'real'?

Cheers,

Tony

another alternative :D

{Little tutorial for real type}
{real type is stores floating point numbers like 3.14 or 0.1234}
{The generic type Real is equivalent to Double.
Type:Real,	Range:5.0 x 10^-324 .. 1.7 x 10^308
Significant digits:15-16	Size in bytes:8}
{if you want to divide 2 numbers then the result always real}
{the same result when the first number is decimal and the second is real}
{so if you work with real numbers then the result always real }


Program get_the_average_ballance;

{$APPTYPE CONSOLE}

Uses
  SysUtils;

Var balance,interest:Real;
    posneg:Integer;

Begin {main}
  WriteLn('Get the average ballance...');

  Randomize;

  balance:=Random(2000); {get the random number}

  posneg:=Random(2);      {again}

  If posneg = 0 Then Begin  {if true then}
    {balance will be negative}
    balance:=balance*-1;
    {and substarct $20 from the money}
    balance:=balance-20;
    {alert the user for the changes}
    WriteLn('You lose $20,sorry');
  End
  Else Begin {in the other way}
    interest:=(balance/100)*3; {it is the same as balance*1.03 the result is real}
    balance:=balance+interest;{add the interest to the balance}
    WriteLn('You got 3%'); {alert the user}
  End;
  WriteLn('The balance is: ',balance:0:0);
  {the colon (:) after balance is the field widenes}
  {the first number after the colon is the number of numbers before the dot}
  {and the second number after the second colon is the number of numbers}
  {after the dot}
  ReadLn; {press the enter button}
End.{end of main}

I like this line:

WriteLn('The balance is: ',balance:0:0);

Very neat.

Sub Xero

I like this line:

WriteLn('The balance is: ',balance:0:0);

Very neat.

Sub Xero

simple pascal syntax...but delphi accepts it too... :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.