Skip to content
This repository was archived by the owner on Feb 1, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.kframework.backend.java.kil.*;
import org.kframework.mpfr.BigFloat;
import org.kframework.mpfr.BinaryMathContext;
import java.math.BigInteger;

/**
* Table of {@code public static} methods on builtin floats.
Expand Down Expand Up @@ -231,6 +232,145 @@ public static IntToken float2int(FloatToken term, TermContext context) {
.withRoundingMode(RoundingMode.DOWN)).toBigIntegerExact());
}

/**
* mint2float converts a Bitvector or MInt {@code term} to an single or double precision float point value.
*/
public static FloatToken mint2float(BitVector term, IntToken precision, IntToken exponentBits, TermContext context) {


int termBitwidth = term.bitwidth();
int expectedPrecision = precision.intValue();
int expectedExponentBits = exponentBits.intValue();

// Sanity Checks.
if(termBitwidth != expectedExponentBits + expectedPrecision) {
throw new IllegalArgumentException("A float with requested precision and exponentBit cannot be obtained from the input MInt");
}

if(termBitwidth != 32 && termBitwidth != 64) {
throw new IllegalArgumentException("Illegal bitwidth provided: "
+ "Only 32 or 64 are supported in order to obtain a single precision or double precision floating point value");
}

// Determine the sign.
boolean sign = !term.extract(0,1).isZero();

// Determine if a double or single precision floating point is requested and fix constants
// based on them.
boolean isDoublePrecision = (precision.intValue() == 53 && exponentBits.intValue() == 11);
int beginExponent = 1, endExponent = 0 , beginSignificand = 0 , endSignificand = 0;
if(isDoublePrecision) {
endExponent = 12;
beginSignificand = 12;
endSignificand = 64;
} else {
endExponent = 9;
beginSignificand = 9;
endSignificand = 32;
}

BitVector biasedExponentBV = term.extract(beginExponent, endExponent);
BitVector significandBV = term.extract(beginSignificand, endSignificand);

// Case I: biasedExponentBV == 0H and significand == 0H, return +0 or -0.
if(biasedExponentBV.isZero() && significandBV.isZero()) {
if(sign) {
return FloatToken.of(BigFloat.negativeZero(precision.intValue()), exponentBits.intValue());
} else {
return FloatToken.of(BigFloat.zero(precision.intValue()), exponentBits.intValue());
}
}

// Case II: biasedExponentBV == all Ones and significandBV == 0H, return +inf/-inf
// biasedExponentBV == all Ones and significandBV != 0H, return nan.
if(biasedExponentBV.eq(BitVector.of(-1, expectedExponentBits)).booleanValue()) {
if(significandBV.isZero()) {
if(sign) {
return FloatToken.of(BigFloat.negativeInfinity(precision.intValue()), exponentBits.intValue());
} else {
return FloatToken.of(BigFloat.positiveInfinity(precision.intValue()), exponentBits.intValue());
}
} else {
return FloatToken.of(BigFloat.NaN(precision.intValue()), exponentBits.intValue());
}
}

// Case III: Sub-Nornals: biasedExponentBV == 0H and significand != 0H
// Normals: biasedExponentBV > 0H and biasedExponentBV < all Ones
// For sub-normals, 0 need to be prepended to significandBV.
// For Normals, 1 need to be appended.
if(biasedExponentBV.isZero()) {
significandBV = BitVector.of(0,1).concatenate(significandBV);
} else {
significandBV = BitVector.of(1,1).concatenate(significandBV);
}


// Compute the unbiased exponent.
BigInteger bias = BigInteger.valueOf(2).pow( exponentBits.intValue() - 1 ).subtract(BigInteger.ONE);
long exponent = biasedExponentBV.unsignedValue().longValue()- bias.longValue();

// Compute the BigFloat.
BinaryMathContext mc = new BinaryMathContext(precision.intValue(), exponentBits.intValue());
return FloatToken.of(new BigFloat(sign,
significandBV.unsignedValue(), exponent, mc),
exponentBits.intValue());
}

/**
* float2mint converts a float point value (single or double precision) {@code term} to a BitVector or MInt
* of bitwidth {@code bitwidth}.
*/
public static BitVector float2mint(FloatToken term, IntToken bitwidth, TermContext context) {
BinaryMathContext mc = getMathContext(term);

int termPrecision = term.bigFloatValue().precision();
long termExponent = term.bigFloatValue().exponent(mc.minExponent, mc.maxExponent);
int termExponentBits = term.exponent();

// Sanity Checks.
if(bitwidth.intValue() != 32 && bitwidth.intValue() != 64) {
throw new IllegalArgumentException("Illegal bitwidth provided: Only 32 or 64 are supported");
}

int expectedPrecision = (bitwidth.intValue() == 32)? 24 : 53;
int expectedExponentBits = (bitwidth.intValue() == 32)? 8 : 11;

if(termPrecision != expectedPrecision || termExponentBits != expectedExponentBits) {
throw new IllegalArgumentException("mismatch precision or exponent bits: "
+ "input floating point precision " + termPrecision + "whereas expected precision based on bitwidth " + expectedPrecision
+ "input floating point exponent bits " + termExponentBits + "whereas expected exponent bits " + expectedExponentBits);
}


BigInteger bias = BigInteger.valueOf(2).pow( termExponentBits - 1 ).subtract(BigInteger.ONE);

// Compute MInt for sign.
boolean sign = term.bigFloatValue().sign();
BitVector signBV = BitVector.of((sign)?1:0,1);

// Compute MInt for significand.
BitVector termSignificand = BitVector.of(term.bigFloatValue().significand(mc.minExponent, mc.maxExponent), mc.precision);
BitVector significandBV = termSignificand.extract(1, mc.precision);

BigFloat termBigFloat = term.bigFloatValue();
// Case I: positive/negative zero and sub-normals
if(termBigFloat.isNegativeZero() || termBigFloat.isPositiveZero() || termBigFloat.isSubnormal(mc.minExponent)) {
BitVector exponentBV = BitVector.of(0, termExponentBits);
return signBV.concatenate(exponentBV.concatenate(significandBV));
}

// Case II: Nan and Infinite(Positive or Negative)
if(termBigFloat.isNaN() || termBigFloat.isInfinite()) {
BitVector exponentBV = BitVector.of(-1, termExponentBits);
return signBV.concatenate(exponentBV.concatenate(significandBV));
}

// Case III: Normalized values
BitVector exponentBV = BitVector.of(termExponent + bias.longValue(), termExponentBits);
return signBV.concatenate(exponentBV.concatenate(significandBV));
}

public static FloatToken ceil(FloatToken term, TermContext context) {
return FloatToken.of(term.bigFloatValue().rint(getMathContext(term)
.withRoundingMode(RoundingMode.CEILING)), term.exponent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ STRING.float2string : org.kframework.backend.java.builtins.BuiltinStringOperatio
STRING.floatFormat : org.kframework.backend.java.builtins.BuiltinStringOperations.floatFormat
FLOAT.int2float : org.kframework.backend.java.builtins.BuiltinFloatOperations.int2float
FLOAT.float2int : org.kframework.backend.java.builtins.BuiltinFloatOperations.float2int
FLOAT.mint2float : org.kframework.backend.java.builtins.BuiltinFloatOperations.mint2float
FLOAT.float2mint : org.kframework.backend.java.builtins.BuiltinFloatOperations.float2mint
STRING.token2string : org.kframework.backend.java.builtins.BuiltinStringOperations.token2string
STRING.string2token : org.kframework.backend.java.builtins.BuiltinStringOperations.string2token
STRING.string2id : org.kframework.backend.java.builtins.BuiltinStringOperations.string2id
Expand Down
3 changes: 3 additions & 0 deletions k-distribution/include/builtin/domains.k
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ endmodule
module FLOAT
imports FLOAT-SYNTAX
imports BOOL
imports MINT
imports INT-SYNTAX

syntax Int ::= precisionFloat(Float) [function, hook(FLOAT.precision)]
Expand Down Expand Up @@ -416,6 +417,8 @@ module FLOAT

syntax Float ::= Int2Float(Int, Int, Int) [function, latex({\\it{}Int2Float}), hook(FLOAT.int2float)]
syntax Int ::= Float2Int(Float) [function, latex({\\it{}Float2Int}), hook(FLOAT.float2int)]
syntax Float ::= MInt2Float(MInt, Int, Int) [function, latex({\\it{}MInt2Float}), hook(FLOAT.mint2float)]
syntax MInt ::= Float2MInt(Float, Int) [function, latex({\\it{}Float2MInt}), hook(FLOAT.float2mint)]

rule sqrtFloat(F:Float) => rootFloat(F, 2)

Expand Down
1 change: 1 addition & 0 deletions k-distribution/tests/builtins/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
skip="pdf" >
</test>
<include file="mint/config.xml" directory="mint" skip="pdf" />
<include file="float/config.xml" directory="float" skip="pdf" />
</tests>
9 changes: 9 additions & 0 deletions k-distribution/tests/builtins/float/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2016 K Team. All Rights Reserved. -->
<tests>
<test definition="convertfloatmint/convertfloatmint-test.k"
extension="convertfloatmint"
programs="convertfloatmint"
results="convertfloatmint" >
</test>
</tests>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2016 K Team. All Rights Reserved.
requires "domains.k"

module CONVERTFLOATMINT-TEST-SYNTAX
imports MINT
imports FLOAT

syntax Task ::= "test" "(" Int "," Float "," Int "," Int "," Int ")" [function]
| "sub" "(" Int "," Int "," Int "," Int "," Int "," Int")" [function]
| "add" "(" Int "," Int "," Int "," Int "," Int "," Int")" [function]
syntax Tasks ::= List{Task, ""}
endmodule

module CONVERTFLOATMINT-TEST
imports CONVERTFLOATMINT-TEST-SYNTAX

configuration <k>$PGM:Tasks</k>

rule T:Task Ts:Tasks => T ~> Ts
rule test(I, F, W, P, E) => eqMInt(mi(W, I), Float2MInt(MInt2Float(mi(W,I), P,E), W))
andBool F ==Float MInt2Float(Float2MInt(F,W), P, E)
andBool MInt2Float(mi(W,I), P,E) ==Float F
andBool eqMInt(Float2MInt(F,W), mi(W,I))

//To test that the precision and exponent information are not modified over Float operations.
rule sub(I, J, K, W, P, E) => eqMInt(Float2MInt(MInt2Float(mi(W, I), P, E) -Float MInt2Float(mi(W, J), P, E), W),
mi(W, K))
rule add(I, J, K, W, P, E) => eqMInt(Float2MInt(MInt2Float(mi(W, I), P, E) +Float MInt2Float(mi(W, J), P, E), W),
mi(W, K))
endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
test(0, 0f,32,24,8)
test(2147483648, -0f, 32,24,8)
test(-2147483648, -0f, 32,24,8)
test(1040187392, 0.125f, 32,24,8)
test(1048576000, 0.25f, 32,24,8)
test(1056964608, 0.5f, 32,24,8)
test(1065353216, 1f, 32,24,8)
test(1073741824, 2f, 32,24,8)
test(1082130432, 4f, 32,24,8)
test(1090519040, 8f, 32,24,8)
test(1052770304, 0.375f, 32,24,8)
test(1061158912, 0.75f, 32,24,8)
test(1069547520, 1.5f, 32,24,8)
test(1077936128, 3f, 32,24,8)
test(1086324736, 6f, 32,24,8)
test(1036831949,0.10000000149011612f, 32,24,8)
test(1045220557, 0.20000000298023224f, 32,24,8)
test(1053609165, 0.40000000596046448f, 32,24,8)
test(1061997773, 0.80000001192092896f, 32,24,8)
test(1399379109, 999999995904f, 32,24,8)
test(1733542428, 1.0000000138484279e+24f, 32,24,8)
test(2067830734, 9.9999996169031625e+35f, 32,24,8)
test(2139095040, Infinityf, 32,24,8)
test(-8388608, -Infinityf, 32,24,8)
test(4286578688, -Infinityf, 32,24,8)
test(-1073741824, -2f, 32,24,8)
test(3221225472, -2f, 32,24,8)
test(1103626240, 25f, 32,24,8)
test(2139095039, 3.402823466E+38f, 32,24,8)
test(8388608, 1.17549435E-38f, 32,24,8)
test(1078530011, 3.1415927410f, 32,24,8)
test(1051372203, 0.333333333333333f, 32,24,8)
test(1095106560, 12.375f, 32,24,8)
test(1116225274, 68.123f, 32,24,8)
test(1077936128, 3f, 32,24,8)
test(3225419776, -3f, 32,24,8)
test(-1069547520, -3f, 32,24,8)
test(1073741825, 2.0000002f, 32,24,8)
test(3221225473, -2.0000002f, 32,24,8)
test(-1073741823, -2.0000002f, 32,24,8)
test(4194304, 5.877472E-39f, 32,24,8)
test(-2143289343, -5.877473E-39f, 32,24,8)
test(2151677953, -5.877473E-39f, 32,24,8)
test(2139095039, 3.4028235E38f, 32,24,8)
test(-8388609, -3.4028235E38f, 32,24,8)
test(4286578687, -3.4028235E38f, 32,24,8)
test(8388607, 1.1754942E-38f, 32,24,8)
test(-2139095041, -1.1754942E-38f, 32,24,8)
test(2155872255, -1.1754942E-38f, 32,24,8)
test(8388608, 1.17549435E-38f, 32,24,8)
test(12582912, 1.7632415E-38f, 32,24,8)
test(16777215, 2.3509886E-38f, 32,24,8)
test(0, 0d,64,53,11)
test(9223372036854775808, -0d, 64,53,11)
test(-9223372036854775808, -0d, 64,53,11)
test(4593671619917905920, 0.125d, 64,53,11)
test(4598175219545276416, 0.25d, 64,53,11)
test(4602678819172646912, 0.5d, 64,53,11)
test(4607182418800017408, 1d, 64,53,11)
test(4611686018427387904, 2d, 64,53,11)
test(4616189618054758400, 4d, 64,53,11)
test(4620693217682128896, 8d, 64,53,11)
test(4600427019358961664, 0.375d, 64,53,11)
test(4604930618986332160, 0.75d, 64,53,11)
test(4609434218613702656, 1.5d, 64,53,11)
test(4613937818241073152, 3d, 64,53,11)
test(4618441417868443648, 6d, 64,53,11)
test(4591870180174331904, 0.10000000149011612d, 64,53,11)
test(4596373779801702400, 0.20000000298023224d, 64,53,11)
test(4600877379429072896, 0.40000000596046448d, 64,53,11)
test(4605380979056443392, 0.80000001192092896d, 64,53,11)
test(4786511204606541824, 999999995904d, 64,53,11)
test(4965913770435018752, 1.0000000138484279e+24d, 64,53,11)
test(5145383438148173824, 9.9999996169031625e+35d, 64,53,11)
test(9218868437227405312, Infinityd, 64,53,11)
test(-4503599627370496, -Infinityd, 64,53,11)
test(18442240474082181120, -Infinityd, 64,53,11)
test(-4611686018427387904, -2d, 64,53,11)
test(13835058055282163712, -2d, 64,53,11)
test(4627730092099895296, 25d, 64,53,11)
test(5183643170565550134, 3.402823466E+38d, 64,53,11)
test(4039728865745034152, 1.17549435E-38d, 64,53,11)
test(4614256656748876136, 3.1415927410d, 64,53,11)
test(4599676419421066575, 0.333333333333333d, 64,53,11)
test(4623156123728347136, 12.375d, 64,53,11)
test(4634494146896484893, 68.123d, 64,53,11)
test(4503599627370496, 2.2250738585072014E-308d, 64,53,11)
test(9227875636482146304, -2.2250738585072014E-308d, 64,53,11)
test(-9218868437227405312, -2.2250738585072014E-308d, 64,53,11)
test(9007199254740991, 4.4501477170144023E-308d, 64,53,11)
test(9232379236109516799, -4.4501477170144023E-308d, 64,53,11)
test(-9214364837600034817, -4.4501477170144023E-308d, 64,53,11)
test(9227875636482146303, -2.225073858507201E-308d, 64,53,11)
test(-9218868437227405313, -2.225073858507201E-308d, 64,53,11)
test(9218868437227405311, 1.7976931348623157E308d, 64,53,11)
test(9214364837600034816, 8.98846567431158E307d, 64,53,11)
test(2251799813685248, 1.1125369292536007E-308d, 64,53,11)
test(9216616637413720064, 1.348269851146737E308d, 64,53,11)
sub(4623156123728347136, 4600427019358961664, 4622945017495814144, 64, 53, 11)
add(4623156123728347136, 4603804719079489536, 4623507967449235456, 64, 53, 11)
sub(1095106560, 1052770304, 1094713344, 32, 24, 8)
add(1095106560, 1059061760, 1095761920, 32, 24, 8)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<k> true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true ( true .Tasks ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) </k>