在我的java代码中找出双算术运算

时间:2017-04-19 08:04:48

标签: java floating-point double

我有很多java项目,我想在我的整个代码中找到双算术运算(+, - ,*,/)。例如,我想从下面的代码中找到a + b行。一旦代码返回所有结果,我将手动将它们更改为某些API。任何人都知道如何编写一个返回所有这些用法的程序?找到以下结果的代码不一定要写成java。我没有在stackoverflow或谷歌中找到这个问题,如果你发现任何问题,请发布。

double a = 0.0, b=0;
if(a+b > 0){
...

2 个答案:

答案 0 :(得分:4)

double上的操作有自己的bytecode instructionsdaddddivdmul等。因此,您可以在课堂上搜索这些操作您项目的文件。

我确信有工具可以做到这一点,所以要搜索那些。

但如果你找不到任何合适的东西,建立自己的东西并不难。在已编译的类上,您可以使用javap -c ClassName来获取类的字节码的相当人类可读的版本。例如,这段代码:

import java.util.Random;

public class Example {
    public static void main(String[] args) {
        Random r = new Random();
        double d1 = r.nextDouble();
        double d2 = r.nextDouble();
        double d3 = d1 + d2;
        System.out.println(d3);
    }
}

...从javap -c产生此输出:

Compiled from "Example.java"
public class Example {
  public Example();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/Random
       3: dup
       4: invokespecial #3                  // Method java/util/Random."":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method java/util/Random.nextDouble:()D
      12: dstore_2
      13: aload_1
      14: invokevirtual #4                  // Method java/util/Random.nextDouble:()D
      17: dstore        4
      19: dload_2
      20: dload         4
      22: dadd
      23: dstore        6
      25: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      28: dload         6
      30: invokevirtual #6                  // Method java/io/PrintStream.println:(D)V
      33: return
}

所以你可以写一个程序:

  1. 获取每个班级的javap -c输出

  2. 查看double相关字节码指令的输出(相当简单的正则表达式工作)

答案 1 :(得分:2)

您可以使用Refaster作为Google errorprone的一部分。

(披露:我在谷歌工作,并定期使用此工具。存在其他工具。我从来没有在现实世界中使用它,所以我不知道它在使用中有多难你的工具链。)

您可以编写一个简单的refaster规则:

class FindTheDoubleOps {
  @BeforeTemplate double plus(double a, double b) { return a + b; }
  @BeforeTemplate double minus(double a, double b) { return a - b; }
  @BeforeTemplate double times(double a, double b) { return a * b; }
  @BeforeTemplate double divide(double a, double b) { return a * b; }
}

将匹配双重操作,如:

double a = 1.0 + 2.0;
double b = methodReturningDouble() + Double.NAN;

等,比你用正则表达式找到的要多得多。

请注意,我未在此处添加@AfterTemplate,但您可以执行以下操作:

class ReplacePlus {
  @BeforeTemplate double before(double a, double b) { return a + b; }
  @AfterTemplate double after(double a, double b) { return myPlus(a, b); }
}

,生成的补丁将包含此替换。

我一直试图按照说明操作。我认为在这里添加一些有用的文档:

$ wget http://repo1.maven.org/maven2/com/google/errorprone/javac/9-dev-r3297-4/javac-9-dev-r3297-4.jar
$ wget http://repo1.maven.org/maven2/com/google/errorprone/error_prone_refaster/2.0.18/error_prone_refaster-2.0.18.jar

$ java -cp javac-9-dev-r3297-4.jar:error_prone_refaster-2.0.18.jar \
  com.google.errorprone.refaster.RefasterRuleCompiler \
  FindTheDoubleOps.java --out $(pwd)/doubleops.refaster

$ wget https://repo1.maven.org/maven2/com/google/errorprone/error_prone_ant/2.0.19/error_prone_ant-2.0.19.jar

$ java -Xbootclasspath/p:error_prone_ant-2.0.19.jar com.google.errorprone.ErrorProneCompiler -XepPatchChecks:refaster:$(pwd)/doubleops.refaster -XepPatchLocation:$(pwd)/patch.patch Example.java

$ java -Xbootclasspath/p:error_prone_ant-2.0.19.jar com.google.errorprone.ErrorProneCompiler -XepPatchChecks:refaster:$(pwd)/doubleops.refaster -XepPatchLocation:$(pwd) Example.java
Example.java:8: warning: [FindTheDoubleOps] 
        double d3 = d1 + d2;
                       ^
  Did you mean 'double d3 = /* match found */ d1 + d2;'?
1 warning
Apr 19, 2017 9:55:38 AM com.google.errorprone.apply.DiffApplier decrementTasks
INFO: Completed 1 files in 6.346 ms
Changes were written to <pwd>/error-prone.patch. Please inspect the file and apply with: patch -p0 -u -i error-prone.patch

(我使用了T.J.Crowder上面的示例代码)。

所以,不是那么难!