1000000000 nanoseconds do not appear to equal a second

447 Views Asked by At

I am creating some magic spells, and obviously I want a delay between each usage.

Now According to google, there are 1000000000 nanoseconds in a second.

However, the magic spell is recharging after less than two seconds.

@EventHandler
public void onInteract(PlayerInteractEvent e){
    Player p = e.getPlayer();
    if (p.getItemInHand().getType().equals(Material.BLAZE_ROD)){
        {
            {
                if (!kam.containsKey(p.getName())) kam.put(p.getName(), (long) 0);
                if (kam.get(p.getName()) < System.nanoTime()){
                    kam.remove(p.getName());
                    kam.put(p.getName(), System.nanoTime() + (1000000000 * 30));
                    //Do magic spell attack here.
                    }
                }
            }else{
                p.sendMessage(ChatColor.AQUA + "Skill recharging!");
            }
}

Obviously my code is trying to add the System.nanoTime() plus 30 seconds, and then checking if the current system nanoTime is greater than the one I put into the hashmap, and if it is, do the spell.

2

There are 2 best solutions below

1
paxdiablo On BEST ANSWER

I suggest you print out the value 1000000000 * 30 and check it. You'll find it's wrapping around because it's too big to fit into an integer.

In other words, the following program:

public class Test
{
    public static void main(String args[])
    {
        System.out.println(1000000000 * 30);
        System.out.println(1000000000L * 30);
    }
}

prints out:

-64771072
30000000000

So, if you use the long variant, it will work fine.

0
Mureinik On

bare numeric literals in Java are treated as ints, and thus your calculation overflows. One way to fix this is to perform the calculation with long literals, by adding L after the literal:

kam.put(p.getName(), System.nanoTime() + (1000000000L * 30L));