|
This is not an issue.
It happens because of the way floating point numbers are stored in memory.
Try this example by changing the value passed to setprecision -
float num = 128.384624;
cout << setiosflags(ios_base::fixed) << setprecision(2) << num << endl;
|
|
|
|
|
use double type instead of float
|
|
|
|
|
Hi,
You ran into precission and rounding problems. This is always a problem when dealing with Floating Point Arithmatic.
The first question is , after setting
stream<<setprecision(2);
You probably typed in quite larger amounts, but I stay with your example, because it hits a fundamental problem, which is not very well understood.
you get things like '511.3999' or '512.100001' I very seldomly use streams, but I know, your setprecission(2) would have printed these as '511.39' and '512.10'
However, I can see where you are coming from. You typed in $511.40, and it appeared elsewhere as $511.39. So you started to investigate. Widened the Precission Spec, and noted that $512.10, was printed as: $ 512.100001!
The Concept of Numbers, Rational Numbers, and Real Numbers is perfect, manipulation of these numbers is always perfect, under the rules of mathematics. At the same time, there is also an Infinite number of Numbers. The Human brain can work with Concepts, and conclude that the square of the square root of 2 equals 2. Computers cannot do that naturally,(Unless if they run an Artificial Inteligence Application designed to do those things). In general, a Computer can work with a Very Large (but Finite) list of Numbers, and the question is how do we encode numbers in real life. Very Large Numbers Very Precice, is very difficult, but then again Who wants to know the US National Budget to the nearest Cent. that's where floats come in. Floats sacrifice speed and storage space for accuracy. If you want to keep account of say funds. Store it in Cents or Fractions of Cents, but essentially as an Integer value.
In other words, you Store it as Cents, but Show it as Dollars,
by sprintf(Buf,"Value \t%c %d.%04d",'$',Val/100,Val%100);
My 30 year adage is:
Storing Money as a Float is nearly always a Daft Idea.
Regards,
Bram van Kampen
|
|
|
|
|
this even happens with the C runtime library!, i use atof and i got the same problems, maybe it is true that is the way the floats are saved in memory as stated before, i even tried double numbers and that even work..
saying this, someone can recommend me a good tutorial on floating numbers manipulation?
Thanks
|
|
|
|
|
materatsu wrote: ...maybe it is true that is the way the floats are saved in memory as stated before...
No maybe about it.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Try http://en.wikipedia.org/wiki/Floating_point[^]. There is a chapter about Accuracy which describes the cause of your problem.
There are several ways to get around this problem, but none of them is exactly simple:
1. The easiest one would be to ignore it, and use mathematical rounding whenever converting between text and floating point numbers. The only thing you really need are two conversion functions, and of course you always have to use those when conversion is required.
2. A somewhat better approach would be to multiply all monetary values by 100 and store them as int (or long ). However, some monetary-based operations may require to consider fractions of Cents, so a factor of 100 may not suffice. Of course, calculations based on these numbers will also be tricky.
3. The best C++ approach would probably be to create a class for your currency, with conversions from and to strings, and basic mathematical operators that take care of however you choose to represent your values internally. While this would cause a lot of effort, there may be existing implementations on the internet that you can use.
|
|
|
|
|
Hey folks!
I am trying to detect when my process is 'forcefully ended' in task manager. I am not trying to prevent this, just want to know this is happening so i can make some log entries and create dumps and such. Googling around suggested hooking 'TerminateProcess' in task manager which i did and it works great as long as the user is ending the process on the 'Processes' tabpage. However -and i think this is more likely to happen- the user kills the program from the 'Applications' tabpage, TerminateProcess in taskmanager isn't invoked. Now my question is: what happens when the user hits 'End Task' on the 'Applications' tabpage? I made a little app and froze it (with Sleep(INFINITE)) to test upon. When i hit 'End Task' on the 'Applications' page and i got asked if i want to end the program i checked where the dialog asking this question came from and it seems to originate from csrss.exe (this was under Windows XP). So it seems that TaskManager somehow passes the job of killing the application to another process.
Do you know how this happens or how i could find out?
Thanks in advance for any suggestions.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
I think in the case of the Applications tab, it simply sends a WM_CLOSE to the application's main window.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I believe so, but when this doesn't work (dispite the WM_CLOSE the software doesn't quit) the user is offered the option of ending the process. When i got this dialog, in task manager on the Applications tab i selected it, right-clicked it and chose 'Go to process' and task manager has shown me 'csrss.exe'. If i hit 'End Task' on the dialog the hooked TerminateProcess doesn't get called in task manager so i believe somehow task manager "hands the process" over to "csrss" to terminate it. Or maybe taskmanager simply kills the process with some other API call. Either way, i'd like to know how it does it so i can 'intercept'. I first tried to hook TerminateProcess in csrss the same way as i did in task manager but i failed at it (i supose because that process belongs to SYSTEM).
P.s.: thanks for answering.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
Code-o-mat wrote: Either way, i'd like to know how it does it so i can 'intercept'.
Seems like a bad idea.
What is your goal - maybe there is another approach.
Googling suggests that in newer windows versions you might be able to set up a ACL for a windows service that prevents exits (taking care as a system reboot must still be allowed.) So it isn't an intercept rather it doesn't allow it in the first place.
modified 28-Jan-12 10:33am.
|
|
|
|
|
I don't want to prevent the user from killing the process if he wishes to do so, i just want to create some log entries (and possibly a minidump) when he does.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
Code-o-mat,
You could probably hook the EndTask function[^] within taskmanager exported from user32 and return TRUE. You might also need to hook NtTerminateProcess[^] inside taskmanager and exported from ntdll. The task manager probably also sends a WM_CLOSE message.
Best Wishes,
-David Delaune
|
|
|
|
|
Hooking EndTask does the trick in Windows XP (sadly doesn't seem to work under Win7), thank you for the idea worth a five point vote.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
Code-o-mat,
I have not tried this on Windows7. Some years back I had to do this on an embedded XP box running maritime dynamic-positioning software. The DP operators would sometimes kill the process and I needed to log this action. I ended up hooking EndTask/NtTerminateProcess. Anyway... this sounds like a worthy challenge for my weekend. I'll fire up WinDbg and see what Win7 is doing differently.
Best Wishes,
-David Delaune
|
|
|
|
|
Thanks for the effort.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
Hey,
It doesn't look like I will have any spare time this weekend for looking into this. I have added it to my TODO list and will look into the issue later this week if time permits.
Best Wishes,
-David Delaune
|
|
|
|
|
In case you care, here's what i found out till now:
-if you hit "End Process" on the "Processes" tab, Task Manager uses TerminateProcess
-if you hit "End Task" on the "Applications" tab, TM either uses EndTask , or it uses SendMessageTimeoutW to send WM_CLOSE to the app. I don't know by what condition it decides which one to use. However, if it considers the application hung (you see "Not Responding" in the "Status" column of its application list) then none of those calls are made but when you hit "End Task", a Windows Error Reporting window pops up asking if i want to look for solutions online. No idea what TM does to do this, i am trying to study the WER API to find out.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
Hey,
Sorry... I assumed that you already knew all that. Some old posts:
what will happen when i terminate a process?[^]
Handling a process termination.[^]
Anyway... could you give me some details about the environment that you intend on using this code? In my case... I was working with special devices with a customized embedded XP and I had control over the operating system... because we designed the OS. I guess what I am asking... is... are you in a similar situation or do you intend on attempting to block this on a standard Windows box. Doing this is an extreme hack... and I would only recommend attepting this in a controlled/closed environment.
Did you hook both NtTerminateProcess and Endtask inside task manager? You can simply ignore the WM_CLOSE message in the target application... or perhaps hook SendMessageTimeoutW and simply return TRUE if the window handle is owned by the target process. I think I used an AppInit DLL to accomplish this on the embedded XP platform.
Keep me informed on your progress... I have been *extremely* busy the last few days but I expect to be finished soon and have some free time starting Friday and through the next weekend. What I wanted to do was grap my old DLL and install it into a Windows7 VM to see if it worked there. I highly doubt anything has changed... when you open the task manager it executes under the credentials of the currently logged in user...
If you want... click 'Email' in my reply and maybe we could collaborate and share some code.
Best Wishes,
-David Delaune
|
|
|
|
|
In C not C++,
I have LPTSTR str = "<xyz>texttext2<h>header</h><xyz>";
I would like to delete all tags NOT NAMED xyz
How do iterate through without deleting the 'xyz' tag ?
|
|
|
|
|
Suggestion. Write a function that searches for the start of the tag and returns the index of the opening <. Write another function that searches for the end of the tag and returns the index of the closing >. Then write a function that 'moves' everything from after the end index to the opening index.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
|
|
|
|
|
Sorry, don't quite follow.
|
|
|
|
|
How about an ASCII picture.
Start End
Index Index
| |
LPTSTR str = "<xyz>texttext2<h>header</h><xyz>";
| |____|
| Stuff to move-+
| |
+--<--< goes here -<--<-+
The first function will return the start index.
The second function will return the end index.
The third function will move all characters after the end index to the end of the string and place them in start index resulting in
LPTSTR str = "<xyz>texttext2<xyz>";
Hope that is clearer.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
|
|
|
|
|
Beautiful picture.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Use strchr(). Look for left angle bracket. Read the next char. If it isnt an 'x' then delete everything up to and including the next right angle bracket with a matching tag.
==============================
Nothing to say.
|
|
|
|
|
Iterate over the string, copying characters from source to destination. If you see a tag not named xyz, stop copying until the matching tag is encountered.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|