473,383 Members | 1,737 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.

rounding to 9's

i'm trying to round my currency string to end in 9. it's for a
pricing application.
this is the function i'm using to get the item in currency:
FormatCurrency(BoxCost, , , , TriState.True)

if an item is 41.87 i want the application to bring it up to 41.89

if an item is 41.84 i want the application to round down to 41.79

does anyone know how i could do this?

Jul 6 '07 #1
18 2185
On Jul 6, 4:06 pm, jdrott1 <jonathandr...@gmail.comwrote:
i'm trying to round my currency string to end in 9. it's for a
pricing application.
this is the function i'm using to get the item in currency:
FormatCurrency(BoxCost, , , , TriState.True)

if an item is 41.87 i want the application to bring it up to 41.89

if an item is 41.84 i want the application to round down to 41.79

does anyone know how i could do this?
You would have to do it manually - just parse the second digit after
the decimal and adjust the value accordingly.

Thanks,

Seth Rowe
Jul 6 '07 #2
Hi Jonathan -

Have you tried rounding to the nearest tenth and subtracting one
hundreth?

Dim myVal As Double
myVal = 41.87
myVal = Math.Round(myVal, 1) - 0.01
Debug.WriteLine(myVal) 'Returns 41.89

myVal = 41.84
myVal = Math.Round(myVal, 1) - 0.01
Debug.WriteLine(myVal) 'Returns 41.79

....sometimes the simplest approaches work the best.

Happy Coding,

-Mark

Jul 6 '07 #3
On Jul 6, 3:50 pm, "Mark S. Milley, MCSD (BinarySwitch)"
<mark.mil...@binaryswitch.comwrote:
Hi Jonathan -

Have you tried rounding to the nearest tenth and subtracting one
hundreth?

Dim myVal As Double
myVal = 41.87
myVal = Math.Round(myVal, 1) - 0.01
Debug.WriteLine(myVal) 'Returns 41.89

myVal = 41.84
myVal = Math.Round(myVal, 1) - 0.01
Debug.WriteLine(myVal) 'Returns 41.79

...sometimes the simplest approaches work the best.

Happy Coding,

-Mark
i'll give it a try. thanks.

Jul 6 '07 #4
Hi Joregen -

How are you getting 4 down and 5 up? Last time I checked, we were
using base ten.

Numbers ending in 0-4 are rounded down, 5-9 are rounded up; 5 on each
side.

Thanks,

-Mark

Jul 7 '07 #5
"jdrott1" <jo***********@gmail.comwrote in message
news:11********************@m36g2000hse.googlegrou ps.com...
i'm trying to round my currency string to end in 9. it's for a
pricing application.
this is the function i'm using to get the item in currency:
FormatCurrency(BoxCost, , , , TriState.True)

if an item is 41.87 i want the application to bring it up to 41.89

if an item is 41.84 i want the application to round down to 41.79

does anyone know how i could do this?
Set two decimal places correcting the error in the Int function for proper
mathematical rounding we have a very simple function:
X = Int(10*(X+0.005))/10

Now set one decimal place mathematical and subtract 1c:
X = Int(10 * (X + 0.06)) / 10 - 0.01
Here, 4 rounds up to 9 as per 5 rounding up to 10
& 3 rounds down to 9 as per 4 rounding down to 0
In the correct mathematical method:
IE +1 inside the brackets compensates -1 outside
just as *10 inside the brackets balances /10 outside.

THUS:

Public Function Nanofy(X as Double) as Double
Nanofy = Int(10 * (X + 0.06)) / 10 - 0.01
End Function

Executing:
Dim x=MsgBox("The Value is: $", CStr(Nanofy(CDble(InputBox(_
"Enter a Value","Enter a Value")))),MsgBoxStyle.OkOnly,"The answer is")

Nanofy(41.84) Returns 41.89
Nanofy(41.83) Returns 41.79
To bias rounding upwards,
simply increment the inner bracket sum in isolation.

SO:
Public Function Nanofy(X as Double) as Double
Nanofy = Int(10 * (X + 0.05)) / 10 - 0.01
End Function

Thus executing:
Dim x=MsgBox("The Value is: $", CStr(Nanofy(CDble(InputBox(_
"Enter a Value","Enter a Value")))),MsgBoxStyle.OkOnly,"The answer is")

Nanofy(41.85) Returns 41.89
Nanofy(41.84) Returns 41.79

Good luck...

--
Timothy Casey GPEMC! >11950 is the nu****@fieldcraft.com.au 2email
Terms & conditions apply. See www.fieldcraft.biz/GPEMC
Discover valid interoperable web menus, IE security, TSR Control,
& the most advanced speed reading application @ www.fieldcraft.biz
Jul 8 '07 #6
"Number 11950 - GPEMC! Replace number with 11950" <nu****@fieldcraft.biz>
wrote in message
news:46***********************@lon-reader.news.telstra.net...

ERRATA:

[SNIP]
Set two decimal places correcting the error in the Int function for proper
mathematical rounding we have a very simple function:
X = Int(10*(X+0.005))/10
[SNIP]

This should read:

Set ONE decimal place correcting the error in the Int function for proper
mathematical rounding we have a very simple function:
X = Int(10*(X+0.005))/10

Cheers

--
Timothy Casey GPEMC! >11950 is the nu****@fieldcraft.com.au 2email
Terms & conditions apply. See www.fieldcraft.biz/GPEMC
Discover valid interoperable web menus, IE security, TSR Control,
& the most advanced speed reading application @ www.fieldcraft.biz
Jul 8 '07 #7
Yeah, that was definately much easier than my solution.

So... In what instance would this give a different result than mine?

Apparently Blind,

-Mark

Jul 8 '07 #8
On Sat, 07 Jul 2007 14:46:36 -0700, "Mark S. Milley, MCSD
(BinarySwitch)" <ma*********@binaryswitch.comwrote:
>Hi Joregen -

How are you getting 4 down and 5 up? Last time I checked, we were
using base ten.

Numbers ending in 0-4 are rounded down, 5-9 are rounded up; 5 on each
side.

Thanks,

-Mark
I said 5 down, 4 up, and the last could go either way.

Because you are using simple Math.Round, which will round off 5s
to the nearest *even* value, e.g. 2.5 becomes 2, 3.5 becomes 4,
4.5 becomes 4, 5.5 becomes 6, and so on. That is great if that
is what you want, but I presumed it did not apply to the original
poster's needs.

Here is your suggestion wrapped in a test program:
---snip---
Private Sub RoundingTest()
Dim ups As Integer = 0
Dim downs As Integer = 0
Dim totalcount As Integer = 0
For value As Decimal = 1D To 1.99D Step 0.01D
Dim roundedvalue As Decimal = Math.Round(value, 1) - 0.01D
Debug.WriteLine(value.ToString("0.00") & ": " &
roundedvalue.ToString("0.00"))
totalcount = totalcount + 1
If roundedvalue < value Then
downs = downs + 1
Else
ups = ups + 1
End If
Next

Debug.WriteLine("------------------------")
Debug.WriteLine("Total: " & totalcount.ToString)
Debug.WriteLine("Ups: " & ups.ToString)
Debug.WriteLine("Downs: " & downs.ToString)

End Sub
---snip---

The results are below: 55 values rounded down, 45 rounded
up.

You can read about various rounding methods here:
http://en.wikipedia.org/wiki/Rounding

Go watch Superman III for another lesson in rounding.

Regards,

Joergen Bech

---snip---
1,00: 0,99
1,01: 0,99
1,02: 0,99
1,03: 0,99
1,04: 0,99
1,05: 0,99
1,06: 1,09
1,07: 1,09
1,08: 1,09
1,09: 1,09
1,10: 1,09
1,11: 1,09
1,12: 1,09
1,13: 1,09
1,14: 1,09
1,15: 1,19
1,16: 1,19
1,17: 1,19
1,18: 1,19
1,19: 1,19
1,20: 1,19
1,21: 1,19
1,22: 1,19
1,23: 1,19
1,24: 1,19
1,25: 1,19
1,26: 1,29
1,27: 1,29
1,28: 1,29
1,29: 1,29
1,30: 1,29
1,31: 1,29
1,32: 1,29
1,33: 1,29
1,34: 1,29
1,35: 1,39
1,36: 1,39
1,37: 1,39
1,38: 1,39
1,39: 1,39
1,40: 1,39
1,41: 1,39
1,42: 1,39
1,43: 1,39
1,44: 1,39
1,45: 1,39
1,46: 1,49
1,47: 1,49
1,48: 1,49
1,49: 1,49
1,50: 1,49
1,51: 1,49
1,52: 1,49
1,53: 1,49
1,54: 1,49
1,55: 1,59
1,56: 1,59
1,57: 1,59
1,58: 1,59
1,59: 1,59
1,60: 1,59
1,61: 1,59
1,62: 1,59
1,63: 1,59
1,64: 1,59
1,65: 1,59
1,66: 1,69
1,67: 1,69
1,68: 1,69
1,69: 1,69
1,70: 1,69
1,71: 1,69
1,72: 1,69
1,73: 1,69
1,74: 1,69
1,75: 1,79
1,76: 1,79
1,77: 1,79
1,78: 1,79
1,79: 1,79
1,80: 1,79
1,81: 1,79
1,82: 1,79
1,83: 1,79
1,84: 1,79
1,85: 1,79
1,86: 1,89
1,87: 1,89
1,88: 1,89
1,89: 1,89
1,90: 1,89
1,91: 1,89
1,92: 1,89
1,93: 1,89
1,94: 1,89
1,95: 1,99
1,96: 1,99
1,97: 1,99
1,98: 1,99
1,99: 1,99
------------------------
Total: 100
Ups: 45
Downs: 55


Jul 8 '07 #9
"Mark S. Milley, MCSD (BinarySwitch)" <ma*********@binaryswitch.comwrote
in message news:11*********************@k79g2000hse.googlegro ups.com...
Yeah, that was definately much easier than my solution.

So... In what instance would this give a different result than mine?

Apparently Blind,

-Mark
I don't know about easier. Just a different way of getting to the same
place.
Also, sometimes doing the math helps centre one's perspective. I call it
'simple' because it's nothing like an algorithm for nailing the trig
function bugs in a 3D polar rotation. Normally a fairly strightforward piece
of math that on paper produces a single formula; The coding requires four
separate formulas because the canned trig functions cannot even correctly
sign the appropriate quadrant. As you can imagine, I'm a little cautious of
invoking canned subroutines because:

1. I don't know what's in them,
2. Sometimes they are slower than the derived subroutine or function,
3. Occasionally they are just plain old dead wrong.

I have to admit, I'd be disappointed if there was any difference in output,
or if your example was slower than mine. Your example did one thing for me,
and that was to emphasise the fact that there are many more improved
functions than I realised. However, reworking canned functions is good
practice for when there is no canned function or method to call on...

By the way, the debug.writeline(myfunction(myvariable)) doesn't seem to work
the way it used to as debug.print(myfunction(myvariable)) did in VB6. Am I
missing a setting or reference?

--
Timothy Casey GPEMC! >11950 is the nu****@fieldcraft.com.au 2email
Terms & conditions apply. See www.fieldcraft.biz/GPEMC
Discover valid interoperable web menus, IE security, TSR Control,
& the most advanced speed reading application @ www.fieldcraft.biz
Jul 8 '07 #10
On Sun, 8 Jul 2007 17:06:26 +1000, "Number 11950 - GPEMC! Replace
number with 11950" <nu****@fieldcraft.bizwrote:
---snip---
>
By the way, the debug.writeline(myfunction(myvariable)) doesn't seem to work
the way it used to as debug.print(myfunction(myvariable)) did in VB6. Am I
missing a setting or reference?
Debug.Print is still available and is exactly equivalent to
Debug.WriteLine.

They both invoke a call to

System.Diagnostics.TraceInternal.WriteLine.

Absent from VS2003 but present in VS2005. Not in a
compatibility namespace, but in one of the core ones
for no good reason at all. I can understand parameter
overloading, but providing two methods that do exactly
the same thing is just plain wrong. Microsoft giving in to
popular demand again, I guess.

But anyway ...

Check Tools -Options -Debugging -General
("Redirect all Output ...") to find out if the text goes
to the Immediate or Output window.

Regards,

Joergen Bech

Jul 8 '07 #11
Ah-ha! I finally found the problem; try this:

Dim ups As Integer = 0
Dim downs As Integer = 0
Dim totalcount As Integer = 0
For value As Decimal = 1D To 1.99D Step 0.01D
Dim roundedvalue As Decimal = Math.Round(value, 1,
MidpointRounding.AwayFromZero) - 0.01D 'This is where the magic
happens
Debug.WriteLine(value.ToString("0.00") & ": " &
roundedvalue.ToString("0.00"))
totalcount = totalcount + 1
If roundedvalue < value Then
downs = downs + 1
Else
ups = ups + 1
End If
Next
Debug.WriteLine("------------------------")
Debug.WriteLine("Total: " & totalcount.ToString)
Debug.WriteLine("Ups: " & ups.ToString)
Debug.WriteLine("Downs: " & downs.ToString)

Not knowing the inner workings of the entire framework, I wasn't aware
that you had to tell Math.Round to use the traditional, elementary
school method of rounding a number. The default way doesn't make a bit
of sense to me.

Anyway, I still feel that my solution
Result = Math.Round(X, 1, MidpointRounding.AwayFromZero) - 0.01
is cleaner and easier to understand than
Result = Int(10 * (X + 0.05)) / 10 - 0.01

Happy Coding,

-Mark

Jul 8 '07 #12
On Sun, 08 Jul 2007 09:02:07 -0700, "Mark S. Milley, MCSD
(BinarySwitch)" <ma*********@binaryswitch.comwrote:

>Not knowing the inner workings of the entire framework, I wasn't aware
that you had to tell Math.Round to use the traditional, elementary
school method of rounding a number. The default way doesn't make a bit
of sense to me.
It makes perfect sense and is the correct choice for the default
behavior, even if it is not appropriate for all applications.

If the resolution is 0.1, you would have

n.1, n.2, n.3, n.4 (rounded down to n)
n.5 (rounded up or down)
n.6, n.7, n.8, n.9 (rounded up to n+1)

So: 4 down, 4 up, and one going either way.

If n.5 was always rounded up, you would have
4 down and 5 up, i.e. the results would be
skewed to one side.

Did you read the Wikipedia article?
>Anyway, I still feel that my solution
Result = Math.Round(X, 1, MidpointRounding.AwayFromZero) - 0.01
is cleaner and easier to understand than
Result = Int(10 * (X + 0.05)) / 10 - 0.01
That's the way I would have written it. Though I would
have written the more direct Math.Floor instead of Int.

Regards,

Joergen Bech

Jul 8 '07 #13
Did you read the Wikipedia article?
Yes; and in my entire professional history, during which I have
created several programs for the accounting departments of several
companies, I have never had a request where they wanted to "round-to-
even". I'm surprised to learn that this is the default behavior in the
framework's Math.Round function, so I thank you for pointing that
out.

I can appreciate the need for this when dealing with statistical data,
where balance is important, but for rounding some prices, as in the
inital request, I think (arbitrarily, IMHO) rounding a number down
because the precedent is an even number is, for most people, counter-
intuitive. For instance, if Jonathan's boss saw the results of a round-
to-even price modifications, I think he would be puzzled to say the
least; then again, I'm assuming he's not a statistician.

Peace,

-Mark

Jul 8 '07 #14
If n.5 was always rounded up, you would have
4 down and 5 up, i.e. the results would be
skewed to one side.
I still don't understand the viewpoint here.
Wikipedia:
With all rounding schemes there are two possible outcomes: increasing the rounding digit by one or leaving it alone.
1.0->1 No Change on Rounding Digit
1.1->1 No Change on Rounding Digit
1.2->1 No Change on Rounding Digit
1.3->1 No Change on Rounding Digit
1.4->1 No Change on Rounding Digit
1.5->2 Rounding Digit Changed
1.6->2 Rounding Digit Changed
1.7->2 Rounding Digit Changed
1.8->2 Rounding Digit Changed
1.9->2 Rounding Digit Changed

Therefore, we have a 50/50 split; 5 changed, and 5 unchanged.

Let's expand this out to a greater level of precision:

1.0000 to 1.4999 = 1 : 5000 unchanged
1.5000 to 1.9999 = 2 : 5000 changed

Are we really biased upward? I suppose--but the whole nature of
rounding is that it makes values less precise, to increase usability.
If we wanted to be perfectly accurate, we should always deal with as
precise of values as possible.

Ah well, maybe I just have a glass-half-full approach to life.

Fin,

-Mark

Jul 8 '07 #15
1.0000 to 1.4999 = 1 : 5000 unchanged
1.5000 to 1.9999 = 2 : 5000 changed

Bah. looking at this, I see the error, finally.
1.4999 ->1.5->2.

A little dense, I am,

-Mark

Jul 8 '07 #16
On Sun, 08 Jul 2007 15:07:51 -0700, "Mark S. Milley, MCSD
(BinarySwitch)" <ma*********@binaryswitch.comwrote:
>1.0000 to 1.4999 = 1 : 5000 unchanged
1.5000 to 1.9999 = 2 : 5000 changed


Bah. looking at this, I see the error, finally.
>1.4999 ->1.5->2.


A little dense, I am,

-Mark
No. Your error is that you are including 1.0000 in the
"down" count. You should have written

1.0000 (no change)
1.0001-1.4999 (4999 down)
1.5000-1.9999 (5000 up)

Here are a few more links:
http://support.microsoft.com/kb/196652
http://www.answers.com/topic/rounding-2?cat=biz-fin

Regards,

Joergen Bech

Jul 9 '07 #17
On Mon, 09 Jul 2007 03:51:48 +0200, Joergen Bech
<jbech<NOSPAM>@<NOSPAM>post1.tele.dkwrote:
>On Sun, 08 Jul 2007 15:07:51 -0700, "Mark S. Milley, MCSD
(BinarySwitch)" <ma*********@binaryswitch.comwrote:
>>1.0000 to 1.4999 = 1 : 5000 unchanged
1.5000 to 1.9999 = 2 : 5000 changed


Bah. looking at this, I see the error, finally.
>>1.4999 ->1.5->2.


A little dense, I am,

-Mark

No. Your error is that you are including 1.0000 in the
"down" count. You should have written

1.0000 (no change)
1.0001-1.4999 (4999 down)
1.5000-1.9999 (5000 up)
Whoops! And on that note, let me correct my test program
myself before anyone else does:
---snip---
Private Sub RoundingTest()
Dim ups As Integer = 0
Dim downs As Integer = 0
Dim totalcount As Integer = 0
For value As Decimal = 1D To 1.99D Step 0.01D
Dim roundedvalue As Decimal = Math.Round(value, 1) - 0.01D
If roundedvalue <(value - 0.01D) Then
Debug.WriteLine(value.ToString("0.00") & ": " &
roundedvalue.ToString("0.00"))
totalcount = totalcount + 1
If roundedvalue < value Then
downs = downs + 1
Else
ups = ups + 1
End If
End If
Next

Debug.WriteLine("------------------------")
Debug.WriteLine("Total: " & totalcount.ToString)
Debug.WriteLine("Ups: " & ups.ToString)
Debug.WriteLine("Downs: " & downs.ToString)

End Sub
---snip---

Now we get 45 ups and 45 downs. No bias, due to the default
round-to-even method.

Had we used

Dim roundedvalue As Decimal = Math.Round(value, 1,
MidpointRounding.AwayFromZero) - 0.01D

the result would have been 50 ups and 40 downs.

I think this thread is well and truly exhausted now.

Regards,

Joergen Bech

Jul 9 '07 #18
I think this thread is well and truly exhausted now.
Agreed. Thanks for the education, Joergen!

-Mark

Jul 9 '07 #19

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

Similar topics

3
by: Norvin Laudon | last post by:
Hi, Can somebody explain the following, from the MSDN documentation for the "System.Convert.ToInt32(double)" function <quote> Return Value value rounded to the nearest 32-bit signed...
4
by: spebola | last post by:
I am using vb.net 2003 professional and I get the following results when using the round method: dim Amount as decimal = 180.255 Amount = Amount.Round(Amount, 2) Amount now contains 180.25. ...
8
by: Zorpiedoman | last post by:
Howcome: Dim D as decimal = .5D msgbox d.Round(D, 0) this returns "0" Now when I went to school .5 rounds UP to 1 not DOWN to zero?????!!! Documentation says this, but what the heck are...
2
by: Jiri Nemec | last post by:
Hello all, I have got one table with rounding values, table contains prices and round types. id price_from price_to rounding 1 0 1500 0.1 2 1500 ...
11
by: cj | last post by:
Lets assume all calculations are done with decimal data types so things are as precise as possible. When it comes to the final rounding to cut a check to pay dividends for example in VB rounding...
5
by: Spoon | last post by:
Hello everyone, I don't understand how the lrint() function works. long lrint(double x); The function returns the nearest long integer to x, consistent with the current rounding mode. It...
206
by: md | last post by:
Hi Does any body know, how to round a double value with a specific number of digits after the decimal points? A function like this: RoundMyDouble (double &value, short numberOfPrecisions) ...
20
by: jacob navia | last post by:
Hi "How can I round a number to x decimal places" ? This question keeps appearing. I would propose the following solution #include <float.h> #include <math.h>
30
by: bdsatish | last post by:
The built-in function round( ) will always "round up", that is 1.5 is rounded to 2.0 and 2.5 is rounded to 3.0. If I want to round to the nearest even, that is my_round(1.5) = 2 # As...
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
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
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: 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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

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.