Skip to content

Commit

Permalink
Add bitwise operations in formula & add round() in spi
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathis-Hu committed Aug 8, 2023
1 parent d7ab370 commit cc5e5f0
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitAND extends TwoArgBitwiseOperation
{
public BitAND()
{
super("bitAND", "Bitwise AND (x, y)", (a, b) -> a & b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitLeftShift extends TwoArgBitwiseOperation
{
public BitLeftShift()
{
super("bitLeftShift", "Bitwise Left Shift (x, y)", (a, b) -> a << b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitNOT extends OneArgBitwiseOperation
{
public BitNOT()
{
super("bitNOT", "Bitwise NOT (x)", a -> ~a);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitOR extends TwoArgBitwiseOperation
{
public BitOR()
{
super("bitOR", "Bitwise OR (x, y)", (a, b) -> a | b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitRightShift extends TwoArgBitwiseOperation
{
public BitRightShift()
{
super("bitRightShift", "Bitwise Right Shift (x, y)", (a, b) -> a >> b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.csstudio.apputil.formula.bitwise;

public class BitXOR extends TwoArgBitwiseOperation
{
public BitXOR()
{
super("bitXOR", "Bitwise XOR (x, y)", (a, b) -> a ^ b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2019-2020 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/
package org.csstudio.apputil.formula.bitwise;

import java.util.List;

import org.csstudio.apputil.formula.spi.FormulaFunction;
import org.epics.vtype.Alarm;
import org.epics.vtype.Display;
import org.epics.vtype.Time;
import org.epics.vtype.VDouble;
import org.epics.vtype.VType;
import org.phoebus.core.vtypes.VTypeHelper;

/** Helper for SPI-provided `long operation(long)`
* @author Mathis Huriez
*/
@SuppressWarnings("nls")
class OneArgBitwiseOperation implements FormulaFunction
{
@FunctionalInterface
public interface OneArgOperation
{
long calc(long arg);
}

private final String name;
private final String description;
private final OneArgOperation operation;

protected OneArgBitwiseOperation(final String name, final String description, final OneArgOperation operation)
{
this.name = name;
this.description = description;
this.operation = operation;
}

@Override
public String getCategory() {
return "bitwise";
}

@Override
public String getName()
{
return name;
}

@Override
public String getDescription()
{
return description;
}

@Override
public List<String> getArguments()
{
return List.of("x");
}

@Override
public VType compute(final VType... args) throws Exception
{
final double arg = VTypeHelper.toDouble(args[0]);
final long a = (long) arg;
if((double) a != arg)
throw new Exception("Operation " + getName() +
" takes integer type but received floating-point type");
final long value = operation.calc(a);
return VDouble.of(value, Alarm.none(), Time.now(), Display.none());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2019-2020 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/
package org.csstudio.apputil.formula.bitwise;

import java.util.List;

import org.csstudio.apputil.formula.spi.FormulaFunction;
import org.epics.vtype.Alarm;
import org.epics.vtype.Display;
import org.epics.vtype.Time;
import org.epics.vtype.VDouble;
import org.epics.vtype.VType;
import org.phoebus.core.vtypes.VTypeHelper;

/** Helper for SPI-provided `long operation(long, long)`
* @author Mathis Huriez
*/
@SuppressWarnings("nls")
class TwoArgBitwiseOperation implements FormulaFunction
{
@FunctionalInterface
public interface TwoArgOperation
{
long calc(long a, long b);
}

private final String name;
private final String description;
private final TwoArgOperation operation;

protected TwoArgBitwiseOperation(final String name, final String description, final TwoArgOperation operation)
{
this.name = name;
this.description = description;
this.operation = operation;
}

@Override
public String getCategory() {
return "bitwise";
}

@Override
public String getName()
{
return name;
}

@Override
public String getDescription()
{
return description;
}

@Override
public List<String> getArguments()
{
return List.of("x", "y");
}

@Override
public VType compute(final VType... args) throws Exception
{
final double arg_a = VTypeHelper.toDouble(args[0]);
final double arg_b = VTypeHelper.toDouble(args[1]);
final long a = (long) arg_a, b = (long) arg_b;
// Check if the conversion is accurate, else, send an exception
if((double) a != arg_a || (double) b != arg_b)
throw new Exception("Operation " + getName() +
" takes integer types but received floating-point types");
final long value = operation.calc(a, b);
return VDouble.of(value, Alarm.none(), Time.now(), Display.none());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ org.csstudio.apputil.formula.math.ExpM1
org.csstudio.apputil.formula.math.Floor
org.csstudio.apputil.formula.math.Log
org.csstudio.apputil.formula.math.Log10
org.csstudio.apputil.formula.math.Round
org.csstudio.apputil.formula.math.Sin
org.csstudio.apputil.formula.math.SinH
org.csstudio.apputil.formula.math.Sqrt
Expand Down Expand Up @@ -55,6 +56,14 @@ org.csstudio.apputil.formula.array.ArrayStatsFunction
org.csstudio.apputil.formula.array.ArrayMaxFunction
org.csstudio.apputil.formula.array.ArrayMinFunction

# Bitwise Operation
org.csstudio.apputil.formula.bitwise.BitAND
org.csstudio.apputil.formula.bitwise.BitOR
org.csstudio.apputil.formula.bitwise.BitXOR
org.csstudio.apputil.formula.bitwise.BitNOT
org.csstudio.apputil.formula.bitwise.BitLeftShift
org.csstudio.apputil.formula.bitwise.BitRightShift

# Alarm
org.csstudio.apputil.formula.alarm.HighestSeverityFunction
org.csstudio.apputil.formula.alarm.MajorAlarmFunction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,24 @@ public void testFunctions() throws Exception {
// usually, should NOT get the same number twice...
assertTrue(rnd != rnd2);
}

f = new Formula("round(12.3)");
assertEquals(12, VTypeHelper.toDouble(f.eval()), epsilon);

f = new Formula("bitOR(5, 7)");
assertEquals(7, VTypeHelper.toDouble(f.eval()), epsilon);

f = new Formula("bitXOR(5, 7)");
assertEquals(2, VTypeHelper.toDouble(f.eval()), epsilon);

f = new Formula("bitRightShift(2, 4)");
assertEquals(0, VTypeHelper.toDouble(f.eval()), epsilon);

f = new Formula("bitRightShift(4, 2)");
assertEquals(1, VTypeHelper.toDouble(f.eval()), epsilon);

f = new Formula("bitNOT(5)");
assertEquals(-6, VTypeHelper.toDouble(f.eval()), epsilon);
}

@Test
Expand Down Expand Up @@ -257,6 +275,9 @@ public void testErrors() throws Exception {

f = new Formula("sqrt(-1)");
assertTrue(Double.isNaN(VTypeHelper.toDouble(f.eval())));

f = new Formula("bitXOR(5.3, 7)");
assertTrue(Double.isNaN(VTypeHelper.toDouble(f.eval())));
}

@Test
Expand Down

0 comments on commit cc5e5f0

Please sign in to comment.