Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to 'Round' (with 2 deimal place) to either X.X5 or X.X0 only? 4

Status
Not open for further replies.

Rock4J

Programmer
Jan 14, 2013
94
MY
I want to round up and down any float/double value (with 2 decimal place), but I want the last decimal to become either 0 or 5 only. For example:

6.42 => 6.40

and

6.45 => 6.45

and

6.47 => 6.50
 
Perhaps not the most elegant method:

Code:
CLOSE all
CLEAR
SET SAFETY off
SET TALK OFF
SET STATUS off


? Flat(6.42)
? Flat(6.45)
? Flat(6.47)


FUNCTION Flat
	PARAMETERS m.DecValue
	PRIVATE m.DecValue,m.RetValue,m.String
	m.RetValue = VAL(RIGHT(Str(m.DecValue,14,2),1))
	IF m.RetValue < 5
		m.RetValue = 0.00
	ELSE
		m.RetValue = 0.05
	ENDIF
	m.RetValue = VAL(LEFT(STR(m.DecValue,14,2),13))+m.retValue
	RETURN(m.RetValue)

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.
 
If 0.05 is your unit, then first divide by 5, then round and then multiply by 5 again:

Round(amount/5,2)*5

And that rounds 6.47 to 6.45 as it's nearer to 6.45 than to 6.50.

Bye, Olaf.
 
He He

I KNEW there would be a good 'maths' way to do it!
Well done Olaf

Code:
CLOSE all
CLEAR
SET SAFETY off
SET TALK OFF
SET STATUS off


? Flat(6.42)
? Flat(6.45)
? Flat(6.47)


FUNCTION Flat
	PARAMETERS m.DecValue
	PRIVATE m.DecValue,m.RetValue,m.String
	m.RetValue = ROUND(m.DecValue/5,2)*5
	RETURN(m.RetValue)

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.
 
The math "secret" is simple:

You see your amounts as multiples of 0.05, then dividing by 5 turns these to multiples of 0.01, after which normal rounding applies. After the rounding you need to multiply with 5 to get multiples of 0.05 again.

You could also put it different, you could multiply all amounts by 20, which makes each 0.05 to 1.00. With that you would then need to round to 0 decimal places and then divide the result by 20 again.

All you need is a factor, that "normalises" to the units you think and want to round to, then you can apply the normal mathematical rounding.

Bye, Olaf.
 
Have a star Olaf

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.
 
Thanks Olaf and GrifMG !! you guys are awesome!! [thumbsup2]
 
Wow! That's cool Tamar! Does the code compatible with VFP6? Thanks so much! [thumbsup2]
 
TamarGranor said:

Hi again, sorry if I'm asking too much. [colorface] I want to ask Tamar, does the following function round FLOAT/DOUBLE type of argument?

Code:
LPARAMETERS nValue, nNearest
LOCAL nRemainder, nReturn
nRemainder = MOD(m.nValue, m.nNearest)
IF m.nRemainder >= m.nNearest/2
nReturn = m.nValue + (m.nNearest - m.nRemainder)
ELSE
nReturn = m.nValue - m.nRemainder
ENDIF
RETURN m.nReturn

If not, then this function can grow larger just to fix my case. I prefer Olaf's kind of code, it's simpler. But your explaination about Rounding in the is awesome! Thanks! [pc1][smile]
 
GriffMG said:
Code:
FUNCTION Flat
PARAMETERS m.DecValue
PRIVATE m.DecValue,m.RetValue,m.String
m.RetValue = VAL(RIGHT(Str(m.DecValue,14,2),1))
IF m.RetValue < 5
	m.RetValue = 0.00
ELSE
	m.RetValue = 0.05
ENDIF
m.RetValue = VAL(LEFT(STR(m.DecValue,14,2),13))+m.retValue
RETURN(m.RetValue)
I think your code is the best answer for my case Griff! I think I'm going to use that. THANKS so much!! I'm not trying to make comparison here, Just trying to find solution. No hard feelings. [pc2] [lol]

Regards,
Rocky
 
I'm sure Olaf and Tamar will take it in good faith.
I also think that Olaf led me to the 'best' result - it's faster and less liable to range errors...
but I'm glad you're happy.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.
 
Indeed MOD does not only give Integer Remainders, eg MOD(1.03,0.05) is .03, and as .03 is larger than .05/2 (0.025) Tamar rounds up.
As a generic solution you could also
Code:
? RoundToUnit(1.54, 1)
? RoundToUnit(1.54, .1)
? RoundToUnit(1.54, .05)
? RoundToUnit(1.53, .05)
? RoundToUnit(1.52, .05)
Procedure RoundToUnit(tnNumber, tnUnit)
   Return Round(tnNumber/tnUnit,0)*tnUnit
EndProc

Bye, Olaf.
 
The MOD function is confusing me.. lolz.. [ponder] [bigsmile] I'll try to study it.. Thanks Griff, Olaf and Tamar.. You guys are really expert! [thumbsup2][thumbsup2][thumbsup2]

Regards,
Rocky
 
MOD is descirbed as "Divides one numeric expression by another numeric expression and returns the remainder."
That's not really to the point. MOD is short for Modulo, which is explained in detail at
In short: MOD divides by a number, but doesn't give that result, instead it gives the remainder of division. You may have learnt this just with natural numbers in school, eg 13 MOD 5 is 3, as 13 can be written as natural factor*5+remainder, if natural factor is 2 and remainder is 3, 13 = 2*5+3, and 13-3 is 10, which is the nearest lower number dividable by 5 with a remainder of 0.

But that principle also works with decimals, eg 13.5 MOD 5 is 3.5, as 13.5 - 3.5 = 10 is again divisable by 5 with a remainder of 0, it's 10 = 2*5+0, the remainder doesn't have to be a natural number. And if the dividend is not a natural number, still the same applies: eg 1.3 MOD .5 is .3 as 1.3-0.3 = 1.0 is divisable by .5 with a remainder of 0, it's 2*.5+0.

That's also the reason, that subtracting the remainder results in a number divisable by the nNearest parameter value in Tamars code, and subtracting the remainder therefore always rounds down. But if the remainder is > nNearest/2, the result has to be rounded up, so nNearest is added to get to the next higher value in units of nNearest. Because that is what rounding is all about: Find the nearest number to the initial number, which is a multiple of nNearest (in Tamars code) or tnUnit (in my code).

Bye, Olaf.
 
Thanks Olaf for the complete explanation and thanks Tamar for sharing! [thumbsup2]

Regards,
Rocky
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top