another (different) rounding problem

Questions and answers on designing your Servoy solutions, database modelling and other 'how do I do this' that don't fit in any of the other categories

Re: another (different) rounding problem

Postby lwjwillemsen » Thu Feb 05, 2015 11:08 am

Hi Robert,

Thank you for your feedback and fosdem report ! 8) PostgreSQL 8)

Regards,
Lambert Willemsen
Vision Development BV
lwjwillemsen
 
Posts: 580
Joined: Sat Mar 14, 2009 5:39 pm
Location: The Netherlands

Re: another (different) rounding problem

Postby Bernd.N » Tue Feb 17, 2015 7:28 pm

omar wrote:And we have to move on so pretty soon I will be taking down http://www.visualfoxpro.com.

That would be a pity, as that site really helps to see differences between Foxpro and JavaScript/Servoy.
Also, the HowTo-Section is of real value for every beginner.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 480
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: another (different) rounding problem

Postby omar » Wed Feb 18, 2015 10:05 am

Thank you, I will think about keeping some of it. Problem is that it is built with .asp pages (.net) which are not supported by one.com (my current hosting provider which I really like). Perhaps I can transfer parts to html5.
Intrasoft / JBS Group, Partner
Omar van Galen
Servoy Developer
omar
 
Posts: 316
Joined: Sat Feb 12, 2011 4:51 pm
Location: Intrasoft, The Netherlands

Re: another (different) rounding problem

Postby Harjo » Tue Sep 19, 2017 4:32 pm

ROCLASI wrote:Interesting discussion :)
Here is a slightly cleaner version of that function:
Code: Select all
function round(_nValue, _nPrecision) {
    var _nAbsValue = Math.abs(_nValue),
        _nDivision = Math.pow(10, _nPrecision);
    return (Math.round(_nAbsValue * _nDivision) / _nDivision) * (_nValue / _nAbsValue);
}


Or if you really wanted to as the (in)famous Oneliner :D :
Code: Select all
function round(_nValue, _nPrecision) {
    return (Math.round(Math.abs(_nValue) * Math.pow(10, _nPrecision)) / Math.pow(10, _nPrecision)) * (_nValue / Math.abs(_nValue));
}


Hi Robert,
I use your round function, but when you try to round 4.725 to nPrecision 2, I would expect it to become 4.73
but it does'nt..
It becomes 4.72

How is this possible?
Harjo Kompagnie
Direct ICT / Servoy Hosting / ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
User avatar
Harjo
 
Posts: 4274
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

Re: another (different) rounding problem

Postby Bernd.N » Tue Sep 19, 2017 4:50 pm

Without any warranties:
(I did read about rounding in stackoverflow some time ago and found that solution below)

Code: Select all
function number_roundToTwo(numberToRound) {   

   // http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript
   // Answer of mrkschan seems to be the best, as toFixed() converts to a string which we do not want
   
   return Math.round((numberToRound + 0.00000001) * 100) / 100;
}
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 480
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: another (different) rounding problem

Postby omar » Tue Sep 19, 2017 4:57 pm

Hi Harjo,

You can use:
Code: Select all
Number(Math.round(4.725+'e2')+'e-2')


Or in a function with support for negative numbers:
Code: Select all
function round(value, decimals) {
  result = Number(Math.round(Math.abs(value)+'e'+decimals)+'e-'+decimals)
  if (value<0) {return result*-1} else {return result}
}
Intrasoft / JBS Group, Partner
Omar van Galen
Servoy Developer
omar
 
Posts: 316
Joined: Sat Feb 12, 2011 4:51 pm
Location: Intrasoft, The Netherlands

Re: another (different) rounding problem

Postby jcompagner » Tue Sep 19, 2017 5:43 pm

Rounding is kind of formatting, so it is something "to display"
That means to me the number that you want to format, must become a String, it can't be a number after rounding because you still have a problem it must fit into the floating point notation (that changes the number again)

so in the 4.725 if you try to round that by first doing *100
472.5
if you round that:
473 (as a whole number)

if you then divide this again by 100
then it very like becomes:
4.72999999

so you see again 4.72

you really should avoid rounding like this, it makes no sense to me to do that.
Because i guess you really want to round to display the value to a user (not to calculate with it because then i do hope you don't make a financial product.....)

so in pseudo code when rounding and going from a number to a string:

var x = 4.725
var y = x * 100; (472.5)
var z = Math.round(y); (473 as a whole number)

var asString = z.toString(); "473"
now calculate a position (how long the string is where the comma must be)
var position = 1; (hard coded for now)
var roundedDisplay = asString .substr(0, position) + "," + asString .substr(position);
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8029
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: another (different) rounding problem

Postby ROCLASI » Tue Sep 19, 2017 6:29 pm

I guess if you DO use it to make a financial product you can always let 'the Pros' handle it (i.e. not JavaScript, but your database) ;)

Code: Select all
function roundValue(value, decimals) {

   // sadly PostgreSQL doesn't allow type modifiers to be placeholders so we must concatenate this in the string :(

   var _ds = databaseManager.getDataSetByQuery("myConnection", "SELECT CAST(? AS NUMERIC(15," + decimals + "))", [value], -1);
   if (_ds.getException()) {
      throw _ds.getException();
   }
   return _ds.getValue(1, 1);

   // NOTE: adjust your datatype casting to match your vendors datatypes (numeric vs number, etc.)
}


roundValue(-8.055, 2)
-8.06

roundValue(4.725, 2)
4.73

Hope this helps
Robert Ivens
ROCLASI Software Solutions / JBS Group, Partner
SAN Developer / Servoy Valued Professional / Servoy Certified Developer
Twitter: @roclasi / @servoyforge
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5230
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: another (different) rounding problem

Postby omar » Wed Sep 20, 2017 9:58 am

Need a string?

Code: Select all
Number(Math.round(4.725+'e2')+'e-2').toString()


The way I see it, exponentials are the perfect solution. What am I missing?
Intrasoft / JBS Group, Partner
Omar van Galen
Servoy Developer
omar
 
Posts: 316
Joined: Sat Feb 12, 2011 4:51 pm
Location: Intrasoft, The Netherlands

Re: another (different) rounding problem

Postby Bernd.N » Wed Sep 20, 2017 10:25 am

jcompagner wrote:Rounding is kind of formatting, so it is something "to display";

I do not agree, because a currency value from "real life" should be represented the same in the database.
Otherwise you get problems at once when you have two invoices with VAT-values of e.g. 8.055 and then want to SUM them to calculate your obligation to pay towards the fiscal authorities.

So best would be numeric type for storage, with two fixed decimals.
However in case of storage as floating-point, 8.0600000001 or 8.059999999 is still much better than the wrong value of 8.055, because there is just no half cent in real life.
So I also do not see why rounding should return the type string.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 480
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: another (different) rounding problem

Postby jcompagner » Wed Sep 20, 2017 11:47 am

the problem is that rounding in the floating point notation that javascript uses is just not really 100% possible
how ever you round it can be that you round to for example 7.25 (because it was 7.245) but 7.25 is in floating point notation: 7.2499999999999
So it is still not correct if after that you just show the 2 decimals...
i guess in this scenario you kind of want to make it 7.2500000001 ....

So lets say you you want to round up after 2 decimals, that kind of means just added 0.005 to it right?
Problem is that 0.005 in js can be 0.0049999

So if you have 7.245 then it would be 7.2499999 and it still wont work..
So lets say we first go to a real integer values:

7.245 * 1000 = 7245

then we add that 0.005 (which is now just 5)
so that kind of works now:

7250

but now divided it again by 1000

then you would think you would get: 7.250
problem is this is suddenly an floating point notation again and you could get: 7.249999999
back to square one...

So maybe we should just not add 5 to it but 5.1
then we would get

7250.1 / 1000 that should result in at least 7.250something

i think this should work, but maybe you guys can think if we then cross boundaries the other way (so we round up to soon what we don't intent to)
like input is:

7.244999999999

how should that round? do you really look only that the 0.004 and see that should not round up. or should you really first look at that 0.0009 and first round that up? so it rolls up to the . and then it does become 7.245 and because of that 7.25? Or should that stay 7.24?

Because if the above should become 7.25 also
then we can do the thing above i guess

*1000 = 7244.9999 + 5.1 = 7250.09999 that will be then 7.250099999

if that shouldn't be rounded to 7.25 then i guess we need:

7244 (and round that to an integer, so remove the .99999) and then add 5.1 so we get: 7249.1 and that will then be 7.24911111 (so rounded to 7.24)
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8029
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: another (different) rounding problem

Postby lwjwillemsen » Wed Sep 20, 2017 2:33 pm

We use our own rounding function throughout our whole Servoy application where rounding is needed, for example rounding to euro cents.
Just counted: used > 2000 times in our code...
Lambert Willemsen
Vision Development BV
lwjwillemsen
 
Posts: 580
Joined: Sat Mar 14, 2009 5:39 pm
Location: The Netherlands

Re: another (different) rounding problem

Postby Harjo » Wed Sep 20, 2017 2:35 pm

lwjwillemsen wrote:We use our own rounding function throughout our whole Servoy application where rounding is needed, for example rounding to euro cents.
Just counted: used > 2000 times in our code...


Are you willing to share?
Harjo Kompagnie
Direct ICT / Servoy Hosting / ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
User avatar
Harjo
 
Posts: 4274
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

Re: another (different) rounding problem

Postby jcompagner » Wed Sep 20, 2017 2:44 pm

i guess the best thing is to store just "cents" in the database...
Not "euros,cents"
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8029
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: another (different) rounding problem

Postby Harjo » Wed Sep 20, 2017 2:47 pm

jcompagner wrote:i guess the best thing is to store just "cents" in the database...
Not "euros,cents"

come on... :shock: Really??? :lol: Sorry... this is too silly!
Harjo Kompagnie
Direct ICT / Servoy Hosting / ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
User avatar
Harjo
 
Posts: 4274
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

PreviousNext

Return to Programming with Servoy

Who is online

Users browsing this forum: No registered users and 1 guest