标签: java

1406
推荐指数
11
解决办法
67万
查看次数

确定整数平方根是否为整数的最快方法

我正在寻找最快的方法来确定一个long值是否是一个完美的正方形(即它的平方根是另一个整数):

  1. 我通过使用内置Math.sqrt() 函数以简单的方式完成了它,但我想知道是否有办法通过将自己限制为仅整数域来更快地完成它.
  2. 维护查找表是不切实际的(因为大约有2 31.5个整数,其平方小于2 63).

这是我现在正在做的非常简单直接的方式:

public final static boolean isPerfectSquare(long n)
{
  if (n < 0)
    return false;

  long tst = (long)(Math.sqrt(n) + 0.5);
  return tst*tst == n;
}
Run Code Online (Sandbox Code Playgroud)

注意:我在许多Project Euler问题中使用此函数.因此,没有其他人必须维护此代码.而这种微优化实际上可以产生影响,因为部分挑战是在不到一分钟的时间内完成每个算法,并且在某些问题中需要将此函数调用数百万次.


我尝试过不同的问题解决方案:

  • 经过详尽的测试后,我发现0.5不需要添加Math.sqrt()的结果,至少在我的机器上没有.
  • 的快速逆平方根增快,但它给了不正确的结果对于n> = 410881.然而,所建议BobbyShaftoe,我们可以使用FISR劈对于n <410881.
  • 牛顿的方法慢了一点Math.sqrt().这可能是因为Math.sqrt()使用类似牛顿方法的东西,但在硬件中实现,因此它比Java快得多.此外,牛顿的方法仍然需要使用双打.
  • 一个修改过的牛顿方法,它使用了一些技巧,只涉及整数数学,需要一些黑客来避免溢出(我希望这个函数适用于所有正64位有符号整数),并且它仍然比它慢Math.sqrt().
  • 二进制斩甚至更慢.这是有道理的,因为二进制斩波平均需要16遍才能找到64位数的平方根.
  • 根据John的测试,or在C++中使用语句比使用语句更快switch,但在Java和C#中,or和之间似乎没有区别switch.
  • 我还尝试制作一个查找表(作为64个布尔值的私有静态数组).然后or我会说,而不是开关或声明if(lookup[(int)(n&0x3F)]) { test } else return false; …

java math optimization perfect-square

1403
推荐指数
22
解决办法
26万
查看次数

如何创建文件并用Java写入?

在Java中创建和写入(文本)文件最简单的方法是什么?

java file-io

1336
推荐指数
26
解决办法
279万
查看次数

为什么在允许某些Unicode字符的注释中执行Java代码?

以下代码生成输出"Hello World!" (不,真的,试试吧).

public static void main(String... args) {

   // The comment below is not a typo.
   // \u000d System.out.println("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)

原因是Java编译器将Unicode字符解析\u000d为新行并转换为:

public static void main(String... args) {

   // The comment below is not a typo.
   //
   System.out.println("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)

从而导致评论被"执行".

由于这可以用来"隐藏"恶意代码或恶意程序员可以设想的任何东西,为什么在评论中允许它?

为什么Java规范允许这样做?

java unicode comments

1326
推荐指数
7
解决办法
7万
查看次数

Apache Camel究竟是什么?

我不明白Camel到底是做什么的.

如果你能用101个单词介绍骆驼:

  • 究竟是什么?
  • 它如何与用Java编写的应用程序交互?
  • 它与服务器一起出现了什么?
  • 这是一个独立的计划吗?

请解释一下Camel是什么.

java soa apache-camel enterprise-integration

1310
推荐指数
21
解决办法
54万
查看次数

如何在Java中连接两个数组?

我需要String在Java中连接两个数组.

void f(String[] first, String[] second) {
    String[] both = ???
}
Run Code Online (Sandbox Code Playgroud)

最简单的方法是什么?

java arrays concatenation add

1299
推荐指数
25
解决办法
104万
查看次数

在调用instanceof之前需要进行空检查吗?

会null instanceof SomeClass退还false还是扔NullPointerException?

java null nullpointerexception

1287
推荐指数
7
解决办法
22万
查看次数

"无法找到或加载主类"是什么意思?

新Java开发人员遇到的一个常见问题是,他们的程序无法运行错误消息: Could not find or load main class ...

这是什么意思,是什么导致它,你应该如何解决它?

java program-entry-point class

1277
推荐指数
25
解决办法
252万
查看次数

将项目导入Eclipse后,"必须覆盖超类方法"错误

任何时候我必须将我的项目重新导入Eclipse(如果我重新安装Eclipse,或者更改了项目的位置),几乎所有重写的方法都没有正确格式化,导致错误:

该方法必须覆盖超类方法

值得注意的是,这是Android项目 - 无论出于何种原因,方法参数值并不总是填充,所以我必须自己手动填充它们.例如:

list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

    //These arguments have their correct names
    public void onCreateContextMenu(ContextMenu menu, View v, 
                                    ContextMenuInfo menuInfo) {                 
    }

});
Run Code Online (Sandbox Code Playgroud)

最初将填充如下:

list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

    //This methods arguments were not automatically provided    
    public void onCreateContextMenu(ContextMenu arg1, View arg2,
                                    ContextMenuInfo arg3) {
    }

});
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果我删除我的代码,并让Eclipse自动重新创建方法,它使用我已经拥有的相同参数名称,所以我真的不知道问题在哪里,除此之外它自动格式化方法我.

这需要手动重新创建所有重写的方法,这变得非常痛苦.如果有人能解释为什么会发生这种情况或如何解决它......我会非常高兴.

也许这是由于我格式化方法的方式,这是在另一个方法的参数内?

java eclipse android overriding superclass

1223
推荐指数
11
解决办法
25万
查看次数

如何在Java中将数字舍入到n个小数位

我想要的是一种将double转换为使用half-up方法进行舍入的字符串的方法 - 即如果要舍入的小数为5,则它总是向上舍入到前一个数字.这是在大多数情况下舍入大多数人所期望的标准方法.

我也希望只显示有效数字 - 即不应该有任何尾随零.

我知道这样做的一种方法是使用该String.format方法:

String.format("%.5g%n", 0.912385);
Run Code Online (Sandbox Code Playgroud)

收益:

0.91239
Run Code Online (Sandbox Code Playgroud)

这很好,但它总是显示5位小数的数字,即使它们不重要:

String.format("%.5g%n", 0.912300);
Run Code Online (Sandbox Code Playgroud)

收益:

0.91230
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用DecimalFormatter:

DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
Run Code Online (Sandbox Code Playgroud)

收益:

0.91238
Run Code Online (Sandbox Code Playgroud)

但是你可以看到这使用了半均匀舍入.也就是说,如果前一个数字是偶数,它将向下舍入.我想要的是这个:

0.912385 -> 0.91239
0.912300 -> 0.9123
Run Code Online (Sandbox Code Playgroud)

在Java中实现这一目标的最佳方法是什么?

java decimal rounding digits

1209
推荐指数
22
解决办法
155万
查看次数