summaryrefslogtreecommitdiff
path: root/chapter17a/src/test/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-28 15:05:08 -0700
committerCliff Click <cliffc@acm.org>2026-10-28 15:05:08 -0700
commit50924bbe7cfeecfe7aec1885dae9bbda0013ac1b (patch)
tree2d04316faa3c73e2a2586de8f95f9b9fb248425f /chapter17a/src/test/java
parent86ce5bc5d5018dcb62054d214b23f7a59b9c0d7d (diff)
downloadSimple-50924bbe7cfeecfe7aec1885dae9bbda0013ac1b.tar.gz
Simple-50924bbe7cfeecfe7aec1885dae9bbda0013ac1b.zip
Remove _phase checks from Arith & Compute
Fix some monotonicty bugs, rounding bugs, in float ops
Diffstat (limited to 'chapter17a/src/test/java')
-rw-r--r--chapter17a/src/test/java/com/seaofnodes/simple/FloatPrecisionTest.java60
1 files changed, 60 insertions, 0 deletions
diff --git a/chapter17a/src/test/java/com/seaofnodes/simple/FloatPrecisionTest.java b/chapter17a/src/test/java/com/seaofnodes/simple/FloatPrecisionTest.java
new file mode 100644
index 00000000..7ad30b46
--- /dev/null
+++ b/chapter17a/src/test/java/com/seaofnodes/simple/FloatPrecisionTest.java
@@ -0,0 +1,60 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.evaluator.Evaluator;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.Type;
+import com.seaofnodes.simple.type.TypeFloat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class FloatPrecisionTest {
+ @Test public void testFloatPrecision() {
+ String[] ops = {"+1.0","-1.0","*3.0","/3.0"};
+ long[] args = {16777216,-16777216,16777215,1};
+ double[] results = {16777217.0,-16777217.0,50331645.0,1.0/3.0};
+ for( int i = 0; i<ops.length; i++ ) {
+ String expr = "x"+ops[i];
+ assertEquals(expr,Double.toString(results[i]),
+ evaluate("f32 x = arg; return "+expr+";",args[i]));
+ assertEquals(expr,Double.toString((float)results[i]),
+ evaluate("f32 x = arg; f32 y = "+expr+"; return y;",args[i]));
+ }
+ }
+
+ private static String evaluate(String src, long arg) {
+ return Evaluator.evaluate(new Parser(src).parse().iterate(),arg).toString();
+ }
+
+ @Test public void testMonotoneCompute() {
+ new Parser("");
+ ArrayList<Type> inputs = new ArrayList<>(Arrays.asList(
+ Type.TOP,Type.BOTTOM,TypeFloat.B32,TypeFloat.BOT,
+ TypeFloat.B32.dual(),TypeFloat.BOT.dual()));
+ for( double value : new double[]{-0.0,0.0,-1.0,1.0,3.0,16777216.0,16777217.0,
+ Double.NaN,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY} )
+ inputs.add(TypeFloat.constant(value));
+ // Isolated analysis inputs; no peepholes can fold the tested nodes.
+ Node lhs = new ConstantNode(Type.BOTTOM);
+ Node rhs = new ConstantNode(Type.BOTTOM);
+ for( Node op : new Node[]{new AddFNode(lhs,rhs),new SubFNode(lhs,rhs),
+ new MulFNode(lhs,rhs),new DivFNode(lhs,rhs)} ) {
+ Type[][] results = new Type[inputs.size()][inputs.size()];
+ for( int i = 0; i<inputs.size(); i++ )
+ for( int j = 0; j<inputs.size(); j++ ) {
+ lhs._type = inputs.get(i);
+ rhs._type = inputs.get(j);
+ results[i][j] = op.compute();
+ }
+ for( int i = 0; i<inputs.size(); i++ )
+ for( int j = 0; j<inputs.size(); j++ )
+ if( inputs.get(i).isa(inputs.get(j)) )
+ for( int k = 0; k<inputs.size(); k++ )
+ if( !results[i][k].isa(results[j][k]) || !results[k][i].isa(results[k][j]) )
+ fail(op.label()+": "+inputs.get(i)+" -> "+inputs.get(j)+
+ ", other="+inputs.get(k)+"; lhs results "+results[i][k]+" -> "+results[j][k]+
+ "; rhs results "+results[k][i]+" -> "+results[k][j]);
+ }
+ }
+}