1000000000 nanoseconds do not appear to equal a second

419 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
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
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));