Double math problem

Discussion in 'Plugin Development' started by jebbo, May 21, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    jebbo

    so, i want to give my players every second some money,

    the problem is, i dont understand how the game comes to this double:

    Code:
    player:
      iRaphi:
        fnd: 5.018000000000001
    Math part:

    Code:java
    1. public void addFND(Player p, double i){
    2. this.getConfig().set("player."+p.getName()+".fnd", getConfig().getDouble("player."+p.getName()+".fnd") + i);
    3. saveConfig();
    4. }


    Usage:

    addFND(a, 0.006);

    5.006 + 0.006 = 5.012 + 0.006 = 5.018


    Why does it come up with this big number?
     
  2. jebbo I didnt quite understood... but maybe this
    Double d = config.get("player." + p.getName() + ".fnd");
    config.set("player." + p.getName() + ".fnd", d + i);

    also, you might want to use UUID instead of names...
     
  3. Offline

    RegalMachine

    jebbo This could be an error with bukkit itself or a rounding error with java. Either way, you can either ignore the issue entirely because adding 1/100000000 to any number isnt going to affect it much, or you can use the NumberFormat class to set the maximum and minimum faction digits to 3 after you input the data
     
  4. RegalMachine might be right...
    have you thought about using integers only?
     
  5. Offline

    jebbo

    Yes, but our currency is made like this already on the website so we really want to use doubles..
     
  6. Offline

    rfsantos1996

    Well, you can format an double using:
    Code:java
    1. new DecimalFormat("0.00").format(i);
    2. // i'll return a string but I belive this format is possible to save as a Double (or it'll give you a "0,00", then just replace every , to . and you can Double.parseDouble again
     
  7. Offline

    Everdras

    Never use primitive floats or doubles for currency.

    Use BigDecimal.

    http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

    The problem is that some base 10 numbers can't be represented exactly in base 2. Just like how 1/3 can be represented exactly in base 3, but not base 10.

    So, if you're a computer, and you speak base 10, and a human who speaks base three asks you to store ".1", you convert it to decimal, only to get .33333333333. You store as much precision as you can. Now, let's say they want you to add ".2" to it. You convert it to base 10, and add .6666... to .3333... and get .9999. You convert this into base 3, and give the user some number slightly lower than 1 (closer to 1 if you're a computer who can store many digits of precision, further from 1 if you can't store as many).

    This is what's happening to you, except that you speak base 10 and the computer speaks base 2.
     
    jebbo, Necrodoom and AoH_Ruthless like this.
  8. Offline

    rsod

    This is related to how computer actually stores float point numbers. Nothing that you can do with it and it's ok, don't worry. If you need to display only some digits, and don't want such big number to be displayed, use DecimalFormat
    Bla bla bla, BigDecimal, precision, blablabla, who needs such precision for currency, esepcially in game, only creating more problems with saving and reading it, making developer write own saving/reading method instead of FileConfiguration use.
     
  9. Offline

    desht


    For storing currency in a Bukkit plugin, it's not a big deal.

    For real-world currency storage, especially in high-volume trading applications, it's a very big deal :)
     
    Garris0n likes this.
Thread Status:
Not open for further replies.

Share This Page