【问题标题】:Algorithm works in Java but not in C算法在 Java 中有效,但在 C 中无效
【发布时间】:2018-09-11 05:01:45
【问题描述】:

我在 Java 中有一个有效的算法实现,但我在 C 中的算法实现不起作用。 该算法接受一个数字并将其转换为 2 字节二进制。 然后它将两个字节分别转换为数字,然后再返回给用户。

Java 实现:

public class Test
{
public static void main(String[] args)
{
    int bytes[] = new int[16];
    int vals[] = getVals(2000, bytes);

    System.out.println(vals[0]);
    System.out.println(vals[1]);
}

public static int[] getVals(int val, int bytes[]) {

      for(int i = 0; i < 16; i++) {

        if(val - Math.pow(2, 15-i) >= 0) {

          val -= Math.pow(2, 15-i);
          bytes[i] = 1; 


        }else bytes[i] = 0;

      }

      int val1 = 0;
      for(int i = 0; i < 8; i++) {
        System.out.print(bytes[i]);
        System.out.print(": ");
        System.out.println(Math.pow(2, 7-i) * bytes[i]);
        val1 += Math.pow(2, 7-i) * bytes[i];

      }

      int val2 = 0;
      for(int i = 8; i < 16; i++) {
        System.out.print(bytes[i]);
        System.out.print(": ");
        System.out.println(Math.pow(2, 7-(i-8)) * bytes[i]);
        val2 += Math.pow(2, 7-(i-8)) * bytes[i];

      }
      int []vals = {val1, val2};

      return vals;
    }
}

Java 代码的输出: val1:7 验证2:208 哪些是正确的输出(我自己计算并检查它们)

在 C 中为 Arduino 实现(不起作用):

#include <math.h>
int vals[2]; 
int bytes[16];
void setup() {

  Serial.begin(9600);
  getVals(2000);
  for(int i = 0; i < 16; i++) Serial.print(bytes[i]);
  Serial.println(" ");
  Serial.println(vals[0]);
  Serial.println(vals[1]);

}

void loop() {
  // put your main code here, to run repeatedly:

}

void getVals(int val) {

  for(int i = 0; i < 16; i++) {

    if(val - pow(2, 15-i) >= 0) {

      val -= pow(2, 15-i);
      bytes[i] = 1; 


    }else bytes[i] = 0;

  }

  int val1 = 0;
  for(int i = 0; i < 8; i++) {
    Serial.print(bytes[i]);
    Serial.print(": ");
    Serial.println(pow(2, 7-i) * bytes[i]);
    val1 += pow(2, 7-i) * bytes[i];

  }

  int val2 = 0;
  for(int i = 8; i < 16; i++) {
    Serial.print(bytes[i]);
    Serial.print(": ");
    Serial.println(pow(2, 7-(i-8)) * bytes[i]);
    val2 += pow(2, 7-(i-8)) * bytes[i];

  }
  Serial.println(val1);
  Serial.println(val2);
  vals[0] = val1;
  vals[1] = val2;

}

C 代码的输出: val1:6 val2:206

-> C 代码的完整输出: 0: 0.00
0: 0.00
0: 0.00
0: 0.00
0: 0.00
1:4.00
1:2.00
1:1.00
1:128.00
1: 64.00
0: 0.00
1:16.00
0: 0.00
0: 0.00
0: 0.00
0: 0.00
6
206
0000011111010000
6
206

有人能指出 C 实现有什么问题吗? 遗憾的是我不能在 Java 中使用算法,因为我需要它在 arduino 上运行。

感谢您提前提供帮助

PS:这是我的第一个 arduino 项目,所以它可能只是一个我找不到的愚蠢的小错误。

【问题讨论】:

  • 据我所知,您的算法有点疯狂。您意识到程序中的数字已经转换为字节,对吧?你为什么这样做?
  • @markspace 我不知道我是否清楚我的算法:我有一个二进制数为 2 个字节大。我必须将每个字节单独存储在芯片上。在芯片上存储东西的功能需要一个应该存储的数字(1字节大小)。我的想法是将输入数字转换为二进制(2字节)并将每个字节转换为我可以存储在芯片上的数字。
  • 你说的是哪个芯片(说真的,很重要)?你意识到如果你只是将一个 int 存储到内存中,字节会自动存储,对吧?
  • arduino nano 的 EEPROM 内存。问题是我一次只能存储一个字节,但是我的数字大于一个字节(2个字节)
  • 1. ints 是四个字节,所以请注意不要遇到溢出问题。 2. 通常,您将所有这些内容写入某种缓冲区,然后将缓冲区存储在 eeprom 中。一些 eeprom 具有必须同时重新编程的“页面”。

标签: java c algorithm arduino implementation


【解决方案1】:

你的 C 代码是正确的(在我的电脑上它给出了你期望的结果)。此外,您的输出似乎还可以:划分 2 个字节并检查自己。

0: 0.00
0: 0.00
0: 0.00
0: 0.00
0: 0.00
1: 4.00
1: 2.00
1: 1.00

1: 128.00
1: 64.00
0: 0.00
1: 16.00
0: 0.00
0: 0.00
0: 0.00
0: 0.00

重新运行并重新检查 arduino 的结果。如果错误仍然存​​在可能取决于平台。

我能想到的一件事是 int 变量可能是 16 位,因此可能存在求和/减去 2^15 的问题。我不认为这是你的情况,但使用 unsigned int 类型或 long 类型。

【讨论】:

    【解决方案2】:

    我会继续在这里给出答案,有一种更简单的方法可以做到这一点,这可能更容易在 C 中工作。

    public class ConvertToBytes {
       public static void main( String[] args ) {
          final int i = 2000;
          System.out.println( "Low byte:" + (i & 0xFF) );
          System.out.println( "High byte:" + (i>>8 & 0xFF) );
       }
    }
    

    输出:

    run:
    Low byte:208
    High byte:7
    BUILD SUCCESSFUL (total time: 2 seconds)
    

    【讨论】:

    • 感谢您的实施。我将尝试为 arduino 实施它
    • 这也是Java中正确的做法。他的 Java 实现很糟糕。根本没有理由使用 pow,他只是不懂数字的二进制表示
    • @sunnyboy4205 二进制数如何在内存中存储,什么是按位运算,以及如何使用它们
    • 答案是“几堂课的材料”,所以你将不得不找一本书或我猜的东西。
    • 好的,谢谢,我会调查一下。但是为什么C代码不起作用的问题仍然没有解决。
    猜你喜欢
    • 2021-04-15
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2020-04-06
    • 1970-01-01
    • 2012-01-25
    相关资源
    最近更新 更多