【问题标题】:Compute sum of increasing numbers in float array using java使用java计算浮点数组中递增数字的总和
【发布时间】:2012-01-21 21:47:37
【问题描述】:

我应该编写一个 Java 程序来总结以下序列:1.0/1.0 + 1.0/2.0 + 1.0/3.0.... + 1.0/15,000,000.0 从 1.0/15,000,000.0 开始按升序排列,然后再按降序排列+ 1.0/14,999,999 一直到 1.0/1.0 使用 32 位浮点。我正在努力弄清楚如何做到这一点,但这是我到目前为止所拥有的(不知道它是否会起作用):

编辑:很抱歉打开这个东西,但我得到的两个答案都是 1.0,我很确定这是不正确的。有谁知道我做错了什么?

public class FloatSum {

public static float increasingSum (float numbers1){
float sum1 = 0;
for (int i = 1; i <= 15000000; i++){ 
    sum1 = sum1 + 1/i; 
    } 
return sum1;
} 

public static float decreasingSum (float numbers2){
float sum2 = 0;
for (int i = 15000000; i >= 1; i--){ 
    sum2 = sum2 + 1/i; 
    } 
return sum2;
}

public static void main(String[] args) {
float sum1 = 0;
float sum2 = 0; 

System.out.println(increasingSum(sum1));
System.out.println(increasingSum(sum2));
}
}

【问题讨论】:

  • 如果我对问题的理解正确,您真的在最后添加2/1 + 2/2 + 2/3 + ... + 2/14999999 + 1/15000000。
  • 1/i 进行整数除法,因此结果始终为 0。
  • 不错的收获。我将“int i = 1”更改为“float i = 1”,现在两个答案都变为无穷大。我还需要改变什么?提前致谢。

标签: java floating-point sum


【解决方案1】:

由于这是家庭作业,我的回答仅限于几个提示:

  1. 您不需要数组:单个标量累加器变量就足够了。将其初始化为零并向其中添加每个术语。
  2. 不要循环遍历总和项,循环遍历 分母(它们是非常方便的整数)。

【讨论】:

  • 谢谢,我会考虑一下,看看我能想出什么。
  • 如果有 15,000,000 个术语,我如何有效地添加每个术语?
  • @user1157541:对于现代计算机来说,1500 万次微不足道的迭代是小菜一碟。如果我处于你的位置,我会先关注正确性,然后再担心性能。
  • 我也会使用 2 个 for 循环,每个循环用于递减和递增顺序。或者...使用一个 for 循环并添加一个额外的操作:abs(15000000 - i) 的效果;)
【解决方案2】:

完全同意 aix。 至于为什么你的代码没有编译:“a”变量是一个浮点数,但是你尝试使用它来访问一个数组(这需要一个 int),并且由于使用浮点数作为 int 是非法的,你得到一个编译错误。您可以通过将 float 转换为 int 来解决错误

numbers1[(int)a]

但这没有用,因为程序仍然是错误的:

  • 访问数组没有意义,因为所有元素都是 0(您确实创建了正确的数组,但所有元素都只是初始化为 0)
  • 由于 for 的测试条件是 a &lt; numbers1.length,因此在最后一次迭代中,您将在代码 numbers1[a+1] 中获得一个 ArrayOutOfBoundException(您将尝试访问第 15000001 个元素)

还有另一个问题,它不会使您的程序失败,但似乎暴露了对 for 循环如何工作的一些误解:具体而言,您在每次迭代时递增 x 变量,但这是徒劳的,因为变量x 仅用于初始化:a = 1/x 部分在执行循环之前只执行一次。 在这里,一个简短的for 入门:

for( Initializer; TestExpr; CountExpr ){ Body }

执行循环的机器将执行以下操作:

  1. 执行Initializer代码
  2. 如果 TestExpr 评估为 false,则转到 6
  3. 执行Body代码
  4. 执行CountExpr代码
  5. 转到 2
  6. 完成!

我可以给你的一个建议是,尝试在纸上使用常用的数学结构来完成你的任务,然后将你的解决方案“移植”到 java。 p>

【讨论】:

  • 感谢所有帮助!现在更有意义了。
【解决方案3】:

您在 for 循环中的逻辑不正确。哈哈,我不太确定你在告诉它做什么,但让我们看看我们是否可以通过它......

暂时忘记其余代码,专注于 for 循环的作用:

您将浮点变量“a”初始化为 1/x。将结束值设置为数组的长度(好)。然后将变量 'a' 增加 1 和 'x' 增加 1...

现在这样想,你将 'a' 初始化为 1/x,使其为 1。它通过值 a = 1 的循环运行。然后它将 'x' 增加 1 并将 'a' 增加1. 现在好好想想,因为这就是你的逻辑有缺陷的地方。这实际上使 x = 2 现在,但您也在使 a = 2。“x”和“a”是自变量。重新阅读 for 循环的定义,看看您是否可以协调您正在尝试做的事情。

现在,循环允许您进行迭代。在这种情况下,您有 30,000,000 个(15,000,000 个“向上计数”和 15,000,000 个“向下计数”)。所以让我们做两个 for 循环,每个循环有 15,000,000 次迭代

for (int i = 1; i <= 15000000; i++){
statements;
}

for (int i = 15000000; i >= 1; i--){
statements;
}

现在,您想将 1.0/1.0 + 1.0/2.0 + ... + 1.0/15,000,000.0 相加。将 sum1 初始化为 0:

float sum1 = 0; 

每次迭代,总和都要加上 1/i。因此,您在每个 for 循环中的语句看起来像

sum1 += 1/i;

与

相同
sum1 = sum1 + 1/i;

你有它。对于第一个循环,每次迭代都会添加 1/i,从 i = 1 开始,到 i = 15,000,000 结束。对于第二个循环,它从 i = 15,000,000 开始添加 1/i,并在 i = 1 处停止。显然,在您的情况下,您可以将 15,000,000 替换为“numbers1.length”。然后返回 sum1,你的所有错误都会像这样消失。

注意:小心你如何约束 for 循环。确保它包含最终值。 (请注意两个循环中的 = 1)这不会对您的代码产生太大影响,并且答案将相同,但将来会很重要。

【讨论】:

  • 感谢所有帮助!现在更有意义了。
【解决方案4】:

如果你愿意,可以使用浮点数,但请看这个:Java:Why should we use BigDecimal instead of Double in the real world?

这叫做精度损失。

【讨论】:

  • 我不喜欢使用浮点数,但这就是任务。我认为您关于精度损失的观点很可能是我们的教授试图教给我们的。
猜你喜欢
  • 1970-01-01
  • 2011-04-08
  • 2011-01-10
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2015-09-09
  • 1970-01-01
相关资源
最近更新 更多