Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Problem with double to int



Permlink Replies: 5 - Last Post: Jun 11, 2017 4:13 AM Last Post By: Alex Belo Threads: [ Previous | Next ]
Doug Hay

Posts: 122
Registered: 5/26/05
Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 8, 2017 3:23 PM
I have a clock with a double that saves the elapsed time to 3 decimals. The double variable contains the value 300.0

I want to display this as elapsed time but just minutes and seconds.

AnsiString Val = FormatDoubleToTime(300.0);

// Val == "299"

AnsiString FormatDoubleToTime(double _Time)
{

// _Time == 300.0

unsigned int IntTime = (unsigned int)_Time;

// IntTime = 299

Not sure why IntTime is 299 and not 300

Thanks for looking!
Doug

Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 8, 2017 4:22 PM   in response to: Doug Hay in response to: Doug Hay
Hi Doug

Doug Hay wrote:

I have a clock with a double that saves the elapsed time to 3 decimals. The
double variable contains the value 300.0

I want to display this as elapsed time but just minutes and seconds.
...
Not sure why IntTime is 299 and not 300

I have just tested this code:

AnsiString FormatDoubleToTime(double _Time)
{
   unsigned int IntTime = (unsigned int)_Time;
 
   return IntTime;
}
void __fastcall TForm1::Button3Click(TObject *Sender)
{
   Caption = FormatDoubleToTime(300.0);
}


In my C++ Berlin and I can NOT confirm this error on my pc, I get 300 in
my Caption as expected.
You should make a small project with code that give the error every time
and post it to attachment group.

Best regards
Asger
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 8, 2017 7:47 PM   in response to: Doug Hay in response to: Doug Hay
Doug Hay wrote:

Not sure why IntTime is 299 and not 300

That would imply that _Time is not exactly 300.0 to begin with, but is
more like 299.9999999999999 instead. Converting a floating-point
number to an integer simply truncates off the decimal.

--
Remy Lebeau (TeamB)
Doug Hay

Posts: 122
Registered: 5/26/05
Re: Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 8, 2017 10:39 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
I'm actually passing a variable that the debugger says is 300.0 (with 18 decimals turned on). I did try passing 300.0 and that worked correctly.

I also found another spot while trying to fix this issue where

_Time = 300.0; // double, is actually already set based on the racer's lap times, but debugger tells me it's 300.0

RaceLength = 300; // int

if (_Time > (double)RaceLength)
{
}

I kind of followed what Remy said, I changed the debugger setting "Floating Point" and the value was "299.999999999999". The default setting showed 300.0. My race hardware only provides 3 decimal places, so I think it would be safe to use

if (_Time + 0.0001) > (double)RaceLength)
{
}

Thanks for the help!
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 9, 2017 9:50 AM   in response to: Doug Hay in response to: Doug Hay
Doug Hay wrote:

I'm actually passing a variable that the debugger says is 300.0 (with
18 decimals turned on).

That does not guarantee that the actual variable data is exactly 300.0
(and your results would imply that it is not). The debugger is likely
just rounding the value up when displaying it as a string.

I did try passing 300.0 and that worked correctly.

Exactly. All the more reason to suspect your variable data does not
contain exactly what you think it does. Where is the variable getting
its value from to begin with? Double check that logic, it is not as
accurate as you think.

_Time = 300.0; // double, is actually already set based on the
racer's lap times, but debugger tells me it's 300.0

As it should be, because it is exactly 300.0, not 299.999999999.

I kind of followed what Remy said, I changed the debugger setting
"Floating Point" and the value was "299.999999999999".

There you go then. There is a big difference between being 300.0 and
being approximately 299.99999999999. Floating-point types are not
exact. This is the reason why you can't do floating-point comparisons
using the '==' operator, for instance. You have to use epsilon
comparisons instead to account for float-point inaccuracies.

My race hardware only provides 3 decimal places

Why not get rid of the decimal altogether? Take a lesson from the
Currency class. It avoids float-point errors in monetary calculations
by using integer math instead of floating-point math. You could do the
same in your code. If your hardware is only accurate to 3 decimal
places, then multiply your values by 1000, do the integer math, and
divide the result by 1000.

--
Remy Lebeau (TeamB)
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Problem with double to int
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 11, 2017 4:13 AM   in response to: Doug Hay in response to: Doug Hay
Doug Hay wrote:

so I think it would be safe to use

if (_Time + 0.0001) > (double)RaceLength)

Yes, this is standard technic in numerical methods.

Also usual constructions are:

double RequiredCalcAccuracy=1e-6; // for example

if(abs(MyFloatVal-TargetVal)<RequiredCalcAccuracy) ...

if(MyFloatVal+RequiredCalcAccuracy>=TargetVal)) ...

if((MyFloatVal+0.5)>=SomeTargetIntVal) ...

and so on.

For more information and possibilities see

std::round, std::lround, std::llround
http://en.cppreference.com/w/cpp/numeric/math/round

std::floor
http://en.cppreference.com/w/cpp/numeric/math/floor

std::ceil
http://en.cppreference.com/w/cpp/numeric/math/ceil

std::trunc
http://en.cppreference.com/w/cpp/numeric/math/trunc

(don't miss "Run this code" in "Example" sections).

--
Alex
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02