【发布时间】:2015-10-17 11:00:53
【问题描述】:
当完整的二叉树为layer 层高时,我有以下代码返回树中的节点数:
public static long nNodesUpToLayer(int layer) {
if (layer < 0) throw new IllegalArgumentException(
"The layer number must be positive: " + layer );
//At layer 0, there must be 1 node; the root.
if (layer == 0) return 1;
//Else, there will be 1 + 2 * (the number of nodes in the previous layer) nodes.
return 1 + (2 * nNodesUpToLayer(layer - 1));
奇怪的是,当我在函数中输入63(产生这个的最小值)时,它返回了-1。在62,它返回9223372036854775807,所以这似乎是由溢出引起的。
难道不应该把 Java 的 long 的最小值 + 溢出的数量还给我吗?不管我给它什么输入(通过62),它总是会返回-1,而不是我期望溢出的看似随机的数字。
我不完全确定如何调试它,因为它是递归的,并且我感兴趣的值只有在函数达到基本情况后才会被评估。
【问题讨论】:
-
我会离开 this 这里然后走开......
-
@Snowman 感谢您的建议。现在我知道一棵高度为
1000的树将有21430172143725346418968500981200036211228096234110672148875007767407021022498722449863967576313917162551893458351062936503742905713846280871969155149397149607869135549648461970842149210124742283755908364306092949967163882534797535118331087892154125829142392955373084335320859663305248773674411336138751节点。我真的很惊讶它计算得如此之快。我预计BigInteger会引入大量开销(或者我听说过),但这几乎是立即完成的。 -
这个函数在技术上是
2^(layer+1) - 1,那你为什么要写一个递归函数而不是简单的return (1L << (layer+1)) - 1呢?这快了几十或几百倍。使用该公式也更容易看出为什么它在 layer = 63 处溢出 -
正如我上面所说,它真的只是
pow(2, layer) - 1 -
不,我没有理由拒绝它。但就我个人而言,单行表达式比长函数更清晰
标签: java integer biginteger integer-overflow