473,383 Members | 1,795 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Problem - casting from double to unsigned int

Hi,

I am working in the project where VC6 code is ported to VC8 (VC++ .Net 2005)

I got a problem when I cast a double value to unsigned int. Problem is I
couldn’t get the proper value after casting (explicitly / implicitly).

Code looks as below :
const double d_a = 100e-9; // 100ns
const double d_b = 20e-9; // 20ns
const unsigned __int32 ui_c = (unsigned __int32) (d_a / d_b)

It is giving ui_c output as 4, which should be 5.

It is working perfectly in VC6. If I create a new console project containing
those 3 lines of code in VC8, it is working and I am getting proper value.

But in PORTED VC8 project which is a DLL I am NOT getting the proper value.

I want to know whether any settings should be applied to get the proper value.

Please reply to this query as soon as possible.

Thanks in advance,
Vinod
Jul 6 '06 #1
11 3492
I am working in the project where VC6 code is ported to VC8 (VC++ .Net
2005)

I got a problem when I cast a double value to unsigned int. Problem is I
couldn't get the proper value after casting (explicitly / implicitly).

Code looks as below :
const double d_a = 100e-9; // 100ns
const double d_b = 20e-9; // 20ns
const unsigned __int32 ui_c = (unsigned __int32) (d_a / d_b)

It is giving ui_c output as 4, which should be 5.

It is working perfectly in VC6. If I create a new console project
containing
those 3 lines of code in VC8, it is working and I am getting proper
value.

But in PORTED VC8 project which is a DLL I am NOT getting the proper
value.

I want to know whether any settings should be applied to get the proper
value.
The fact that it worked in VC6 means that you got lucky.
You really should not expect to get exact integer result from floating point
operations.

search google for
'what every programmer should know about floating point'
and you will find a number of explanations.

to work around this problem you have to work with tolerances / error margins

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Jul 6 '06 #2
You are correct, But It is working fine in the VC8 (Console) project,

I don't know why it is not giving the proper value in the PORTED VC8 (DLL)
project...

Do you have any idea about optimization setting in the project property?
I think that might cause the problem. But I don't know exactly.

-Thanks,
Vinod

"Bruno van Dooren" wrote:
I am working in the project where VC6 code is ported to VC8 (VC++ .Net
2005)

I got a problem when I cast a double value to unsigned int. Problem is I
couldn't get the proper value after casting (explicitly / implicitly).

Code looks as below :
const double d_a = 100e-9; // 100ns
const double d_b = 20e-9; // 20ns
const unsigned __int32 ui_c = (unsigned __int32) (d_a / d_b)

It is giving ui_c output as 4, which should be 5.

It is working perfectly in VC6. If I create a new console project
containing
those 3 lines of code in VC8, it is working and I am getting proper
value.

But in PORTED VC8 project which is a DLL I am NOT getting the proper
value.

I want to know whether any settings should be applied to get the proper
value.

The fact that it worked in VC6 means that you got lucky.
You really should not expect to get exact integer result from floating point
operations.

search google for
'what every programmer should know about floating point'
and you will find a number of explanations.

to work around this problem you have to work with tolerances / error margins

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Jul 6 '06 #3
>Do you have any idea about optimization setting in the project property?

Try changing the floating point model switch /fp to whatever works for
you in the console test project.

Dave
Jul 6 '06 #4
I tried the same whatever I used in the console test project in the PORTED
VC8 project also. But I am not getting the proper value here. Anything else I
need to do?

-Thanks,
Vinod

"David Lowndes" wrote:
Do you have any idea about optimization setting in the project property?

Try changing the floating point model switch /fp to whatever works for
you in the console test project.

Dave
Jul 7 '06 #5
>I tried the same whatever I used in the console test project in the PORTED
>VC8 project also. But I am not getting the proper value here. Anything else I
need to do?
How about similar settings in the building of the calling program?

Other than that I can only reiterate what Bruno said in that you
should never expect to get exact results with FP operations - they
just don't work that way!

Dave
Jul 7 '06 #6
chl

"Vinod" <Vi***@discussions.microsoft.comwrote in message news:F1**********************************@microsof t.com...
Hi,

I got a problem when I cast a double value to unsigned int. Problem is I
couldn't get the proper value after casting (explicitly / implicitly).

Code looks as below :
const double d_a = 100e-9; // 100ns
const double d_b = 20e-9; // 20ns
const unsigned __int32 ui_c = (unsigned __int32) (d_a / d_b)

It is giving ui_c output as 4, which should be 5.
As others have stated, fp is inherently inexact, so in some scenarios your division
yields perhaps 4.9999999999, and the cast will then truncate it to 4.

You have to _round_ the division result before casting. An easy way to do this is to
add half of the rounding factor before truncating, i.e. (int) ((a / b) + 0.5)
>I want to know whether any settings should be applied to get the proper value.
You cannot solve this using settings, as your code is not correct.

Jul 7 '06 #7
Vinod wrote:
You are correct, But It is working fine in the VC8 (Console) project,
'working fine' for me means it could be giving you either 4 or 5. Either
answer is equally fine for that code. In theory, you could get 4 or 5 at
random and it would still be working fine.
I don't know why it is not giving the proper value in the PORTED VC8 (DLL)
project...
It is giving the proper value in both projects.
Do you have any idea about optimization setting in the project property?
I think that might cause the problem. But I don't know exactly.
You might be able to make it return one of the two proper values with
different settings, but this is very unreliable, and might not work if
you switch to a different CPU.

Tom
Jul 7 '06 #8
You are absolutely correct. The division result (double value) might be some
4.9999999 and casting into "unsigned int32" is giving the final value as 4.

What I am exactly asking is why it is giving the value as 4 instead of 5 in
the PORTED VC8 (DLL) project alone, while I got the expected value 5 in
existing VC6 project and Test VC8 (console) project.

It causes problem in so many places in the PORTED VC8 (DLL) project, I can’t
go to each and every place and can’t change as you suggested. It is not good
practice, right? If there are any property settings which can be changed, it
will be good. If there are no property settings or any other solutions for
this problem, obviously I need to go to every place and have to change the
code...

So before that, I would like to confirm this with you people... Please do
answer me...

-Thanks,
Vinod

"chl" wrote:
>
"Vinod" <Vi***@discussions.microsoft.comwrote in message news:F1**********************************@microsof t.com...
Hi,

I got a problem when I cast a double value to unsigned int. Problem is I
couldn't get the proper value after casting (explicitly / implicitly).

Code looks as below :
const double d_a = 100e-9; // 100ns
const double d_b = 20e-9; // 20ns
const unsigned __int32 ui_c = (unsigned __int32) (d_a / d_b)

It is giving ui_c output as 4, which should be 5.

As others have stated, fp is inherently inexact, so in some scenarios your division
yields perhaps 4.9999999999, and the cast will then truncate it to 4.

You have to _round_ the division result before casting. An easy way to do this is to
add half of the rounding factor before truncating, i.e. (int) ((a / b) + 0.5)
I want to know whether any settings should be applied to get the proper value.

You cannot solve this using settings, as your code is not correct.
Jul 10 '06 #9
"Working fine" means it is giving the proper or expected result i.e. 5 in the
Test VC8 (console) project.

What I am exactly asking is why it is giving the value as 4 instead of 5 in
the PORTED VC8 (DLL) project alone, while I got the expected value 5 in
existing VC6 project and Test VC8 (console) project.

Please do reply the solution of the problem or suggestion to avoid the
problem.

-Thanks,
Vinod

"Tom Widmer [VC++ MVP]" wrote:
Vinod wrote:
You are correct, But It is working fine in the VC8 (Console) project,

'working fine' for me means it could be giving you either 4 or 5. Either
answer is equally fine for that code. In theory, you could get 4 or 5 at
random and it would still be working fine.
I don't know why it is not giving the proper value in the PORTED VC8 (DLL)
project...

It is giving the proper value in both projects.
Do you have any idea about optimization setting in the project property?
I think that might cause the problem. But I don't know exactly.

You might be able to make it return one of the two proper values with
different settings, but this is very unreliable, and might not work if
you switch to a different CPU.

Tom
Jul 10 '06 #10
Vinod wrote:
You are absolutely correct. The division result (double value) might be some
4.9999999 and casting into "unsigned int32" is giving the final value as 4.

What I am exactly asking is why it is giving the value as 4 instead of 5 in
the PORTED VC8 (DLL) project alone, while I got the expected value 5 in
existing VC6 project and Test VC8 (console) project.
It relates to how much of the division is done at compile time versus
runtime, what mode the CPU is set to when the division is performed and
how the optimizer modifies the code. You don't really have explicit
control over all this, and you can change the results of calculations
with apparently innocuous changes (e.g.
double d = 10.0;
double e = 5.0;
double f = d / e;
vs
double f = 10.0/5.0;
)

The /Op option may give you more consistent results, but certainly not
in all cases.
It causes problem in so many places in the PORTED VC8 (DLL) project, I can’t
go to each and every place and can’t change as you suggested. It is not good
practice, right?
It is certainly good practice to fix broken code.

If there are any property settings which can be changed, it
will be good. If there are no property settings or any other solutions for
this problem, obviously I need to go to every place and have to change the
code...

So before that, I would like to confirm this with you people... Please do
answer me...
If you do find a setting that seems to work, are you confident that
every double calculation will produce the same result as before? Do you
have some kind of regression test to check this? If not, you are
probably better off changing the code. Regarding settings, you could try
disabling all optimizations and adding /Op to see whether that fixes it,
and then start adding them back in one at a time to see which one causes
the "problem".

Tom
Jul 10 '06 #11
>It causes problem in so many places in the PORTED VC8 (DLL) project, I
>can't go to each and every place and can't change as you suggested. It is
not good practice, right?

It is certainly good practice to fix broken code.
The best solution is to create a function like this:
int myDiv(double a, double b);

That performs the operation you expect with correct rounding.
Then you go through your code and replace all division operations of that
king by your new div function.

Changing compiler settings is not a good solution because the assumptions in
the code are flawed.
There is NO way to guarantee that the code will produce the result that you
expect otherwise.
Even if it would work now for the values you test it on, the problem could
come back if your program runs on another CPU.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Jul 11 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: William Payne | last post by:
Hello, I want to display the address a pointer points to in hexadecimal form in the same way my debugger displays it. Say I have P* ptr; where P is some type. I tried: std::sprintf(message,...
17
by: Jon Slaughter | last post by:
I'm having a little trouble understanding what the slicing problem is. In B.S.'s C++ PL3rdEd he says "Becayse the Employee copy functions do not know anything about Managers, only the Employee...
231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
8
by: Mantorok Redgormor | last post by:
I have ran into a problem where I have a struct that has a member which contains a pointer to function and is initialized to a function in the initializer list. With my array of structs of this...
6
by: Roman Mashak | last post by:
Hello, All! I would like to use this macro to substitute type of variable, but it doesn't work by now: typedef enum table_type_e { INT, FLOAT, DOUBLE } table_type_t;
14
by: mr_semantics | last post by:
I have been reading about the practise of casting values to unsigned char while using the <ctype.h> functions. For example, c = toupper ((unsigned char) c); Now I understand that the standard...
1
by: Joannes Vermorel | last post by:
I am currently trying to port a small open source scientfic library written in C++ to .Net. The code (including the VS solution) could be found at http://www.vermorel.com/opensource/selfscaling.zip...
2
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c...
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.