Uncommented hex floating point parser

This commit is contained in:
Igor Chevdar
2017-06-20 14:35:30 +03:00
parent 501a40501e
commit ed0c78167b
4 changed files with 370 additions and 349 deletions
+11
View File
@@ -53,6 +53,17 @@ KDouble Konan_NumberConverter_ceil(KDouble x) {
} }
void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value); void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value);
KDouble Konan_long_bits_to_double(KLong x);
}
KDouble Konan_long_bits_to_double(KLong x) {
union {
int64_t x;
double d;
} tmp;
tmp.x = x;
return tmp.d;
} }
KDouble createDouble (const char *s, KInt e); KDouble createDouble (const char *s, KInt e);
+12 -2
View File
@@ -39,8 +39,18 @@
#define DEFAULT_WIDTH MAX_ACCURACY_WIDTH #define DEFAULT_WIDTH MAX_ACCURACY_WIDTH
extern "C" { extern "C" {
KFloat KFloat Konan_FloatingPointParser_parseFloatImpl (KString s, KInt e);
Konan_FloatingPointParser_parseFloatImpl (KString s, KInt e);
KFloat Konan_int_bits_to_float(KInt x);
}
KFloat Konan_int_bits_to_float(KInt x) {
union {
int32_t x;
float f;
} tmp;
tmp.x = x;
return tmp.f;
} }
KFloat createFloat1 (U_64 * f, IDATA length, KInt e); KFloat createFloat1 (U_64 * f, IDATA length, KInt e);
@@ -336,8 +336,7 @@ object FloatingPointParser {
// See if it could be a hexadecimal representation. // See if it could be a hexadecimal representation.
if (parseAsHex(s)) { if (parseAsHex(s)) {
TODO("Hex format is not supported") return HexStringParser.parseDouble(s)
//return HexStringParser.parseDouble(s)
} }
val info = initialParse(s, length) val info = initialParse(s, length)
@@ -389,8 +388,7 @@ object FloatingPointParser {
// See if it could be a hexadecimal representation. // See if it could be a hexadecimal representation.
if (parseAsHex(s)) { if (parseAsHex(s)) {
TODO("Hex format is not supported") return HexStringParser.parseFloat(s)
//return HexStringParser.parseFloat(s)
} }
val info = initialParse(s, length) val info = initialParse(s, length)
@@ -17,350 +17,352 @@
package konan.internal package konan.internal
// TODO: Enable as soon as regexes are supported. import kotlin.text.regex.*
@SymbolName("Konan_int_bits_to_float")
private external fun intBitsToFloat(x: Int): Float
@SymbolName("Konan_long_bits_to_double")
private external fun longBitsToDouble(x: Long): Double
/* /*
* Parses hex string to a single or double precision floating point number. * Parses hex string to a single or double precision floating point number.
*/ */
//internal class HexStringParser(private val EXPONENT_WIDTH: Int, private val MANTISSA_WIDTH: Int) { internal class HexStringParser(private val EXPONENT_WIDTH: Int, private val MANTISSA_WIDTH: Int) {
//
// private val EXPONENT_BASE: Long private val EXPONENT_BASE: Long
//
// private val MAX_EXPONENT: Long private val MAX_EXPONENT: Long
//
// private val MIN_EXPONENT: Long private val MIN_EXPONENT: Long
//
// private val MANTISSA_MASK: Long private val MANTISSA_MASK: Long
//
// private var sign: Long = 0 private var sign: Long = 0
//
// private var exponent: Long = 0 private var exponent: Long = 0
//
// private var mantissa: Long = 0 private var mantissa: Long = 0
//
// private var abandonedNumber = "" //$NON-NLS-1$ private var abandonedNumber = "" //$NON-NLS-1$
//
// init { init {
// this.EXPONENT_BASE = (-1L shl (EXPONENT_WIDTH - 1)).inv()
// this.EXPONENT_BASE = (-1L shl EXPONENT_WIDTH - 1).inv() this.MAX_EXPONENT = (-1L shl EXPONENT_WIDTH).inv()
// this.MAX_EXPONENT = (-1L shl EXPONENT_WIDTH).inv() this.MIN_EXPONENT = (-(MANTISSA_WIDTH + 1)).toLong()
// this.MIN_EXPONENT = (-(MANTISSA_WIDTH + 1)).toLong() this.MANTISSA_MASK = (-1L shl MANTISSA_WIDTH).inv()
// this.MANTISSA_MASK = (-1L shl MANTISSA_WIDTH).inv() }
// }
// private fun parse(hexString: String): Long {
// private fun parse(hexString: String): Long { val hexSegments = getSegmentsFromHexString(hexString)
// val hexSegments = getSegmentsFromHexString(hexString) val signStr = hexSegments[0]
// val signStr = hexSegments[0] val significantStr = hexSegments[1]
// val significantStr = hexSegments[1] val exponentStr = hexSegments[2]
// val exponentStr = hexSegments[2]
// parseHexSign(signStr)
// parseHexSign(signStr) parseExponent(exponentStr)
// parseExponent(exponentStr) parseMantissa(significantStr)
// parseMantissa(significantStr)
// sign = sign shl (MANTISSA_WIDTH + EXPONENT_WIDTH)
// sign = sign shl (MANTISSA_WIDTH + EXPONENT_WIDTH) exponent = exponent shl MANTISSA_WIDTH
// exponent = exponent shl MANTISSA_WIDTH return sign or exponent or mantissa
// return sign or exponent or mantissa }
// }
// /*
// /* * Parses the sign field.
// * Parses the sign field. */
// */ private fun parseHexSign(signStr: String) {
// private fun parseHexSign(signStr: String) { this.sign = (if (signStr == "-") 1 else 0).toLong() //$NON-NLS-1$
// this.sign = (if (signStr == "-") 1 else 0).toLong() //$NON-NLS-1$ }
// }
// /*
// /* * Parses the exponent field.
// * Parses the exponent field. */
// */ private fun parseExponent(exponentStr: String) {
// private fun parseExponent(exponentStr: String) { var exponentStr = exponentStr
// var exponentStr = exponentStr val leadingChar = exponentStr[0]
// val leadingChar = exponentStr[0] val expSign = if (leadingChar == '-') -1 else 1
// val expSign = if (leadingChar == '-') -1 else 1 if (!leadingChar.isDigit()) {
// if (!Character.isDigit(leadingChar)) { exponentStr = exponentStr.substring(1)
// exponentStr = exponentStr.substring(1) }
// }
// try {
// try { exponent = expSign * exponentStr.toLong()
// exponent = expSign * exponentStr.toLong() checkedAddExponent(EXPONENT_BASE)
// checkedAddExponent(EXPONENT_BASE) } catch (e: NumberFormatException) {
// } catch (e: NumberFormatException) { exponent = expSign * Long.MAX_VALUE
// exponent = expSign * Long.MAX_VALUE }
// }
// }
// }
// /*
// /* * Parses the mantissa field.
// * Parses the mantissa field. */
// */ private fun parseMantissa(significantStr: String) {
// private fun parseMantissa(significantStr: String) { val strings = significantStr.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() //$NON-NLS-1$
// val strings = significantStr.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() //$NON-NLS-1$ val strIntegerPart = strings[0]
// val strIntegerPart = strings[0] val strDecimalPart = if (strings.size > 1) strings[1] else "" //$NON-NLS-1$
// val strDecimalPart = if (strings.size > 1) strings[1] else "" //$NON-NLS-1$
// var significand = getNormalizedSignificand(strIntegerPart, strDecimalPart)
// var significand = getNormalizedSignificand(strIntegerPart, strDecimalPart) if (significand == "0") { //$NON-NLS-1$
// if (significand == "0") { //$NON-NLS-1$ setZero()
// setZero() return
// return }
// }
// val offset = getOffset(strIntegerPart, strDecimalPart)
// val offset = getOffset(strIntegerPart, strDecimalPart) checkedAddExponent(offset.toLong())
// checkedAddExponent(offset.toLong())
// if (exponent >= MAX_EXPONENT) {
// if (exponent >= MAX_EXPONENT) { setInfinite()
// setInfinite() return
// return }
// }
// if (exponent <= MIN_EXPONENT) {
// if (exponent <= MIN_EXPONENT) { setZero()
// setZero() return
// return }
// }
// if (significand.length > MAX_SIGNIFICANT_LENGTH) {
// if (significand.length > MAX_SIGNIFICANT_LENGTH) { abandonedNumber = significand.substring(MAX_SIGNIFICANT_LENGTH)
// abandonedNumber = significand.substring(MAX_SIGNIFICANT_LENGTH) significand = significand.substring(0, MAX_SIGNIFICANT_LENGTH)
// significand = significand.substring(0, MAX_SIGNIFICANT_LENGTH) }
// }
// mantissa = significand.toLong(HEX_RADIX)
// mantissa = significand.toLong(HEX_RADIX)
// if (exponent >= 1) {
// if (exponent >= 1) { processNormalNumber()
// processNormalNumber() } else {
// } else { processSubNormalNumber()
// processSubNormalNumber() }
// }
// }
// }
// private fun setInfinite() {
// private fun setInfinite() { exponent = MAX_EXPONENT
// exponent = MAX_EXPONENT mantissa = 0
// mantissa = 0 }
// }
// private fun setZero() {
// private fun setZero() { exponent = 0
// exponent = 0 mantissa = 0
// mantissa = 0 }
// }
// private fun signum(x: Long) = when {
// private fun signum(x: Long) = when { x == 0L -> 0
// x == 0L -> 0 x > 0L -> 1
// x > 0L -> 1 else -> -1
// else -> -1 }
// }
// /*
// /* * Sets the exponent variable to Long.MAX_VALUE or -Long.MAX_VALUE if
// * Sets the exponent variable to Long.MAX_VALUE or -Long.MAX_VALUE if * overflow or underflow happens.
// * overflow or underflow happens. */
// */ private fun checkedAddExponent(offset: Long) {
// private fun checkedAddExponent(offset: Long) { val result = exponent + offset
// val result = exponent + offset val expSign = signum(exponent)
// val expSign = signum(exponent) if (expSign * signum(offset) > 0 && expSign * signum(result) < 0) {
// if (expSign * signum(offset) > 0 && expSign * signum(result) < 0) { exponent = expSign * Long.MAX_VALUE
// exponent = expSign * Long.MAX_VALUE } else {
// } else { exponent = result
// exponent = result }
// } }
// }
// private fun processNormalNumber() {
// private fun processNormalNumber() { val desiredWidth = MANTISSA_WIDTH + 2
// val desiredWidth = MANTISSA_WIDTH + 2 fitMantissaInDesiredWidth(desiredWidth)
// fitMantissaInDesiredWidth(desiredWidth) round()
// round() mantissa = mantissa and MANTISSA_MASK
// mantissa = mantissa and MANTISSA_MASK }
// }
// private fun processSubNormalNumber() {
// private fun processSubNormalNumber() { var desiredWidth = MANTISSA_WIDTH + 1
// var desiredWidth = MANTISSA_WIDTH + 1 desiredWidth += exponent.toInt()//lends bit from mantissa to exponent
// desiredWidth += exponent.toInt()//lends bit from mantissa to exponent exponent = 0
// exponent = 0 fitMantissaInDesiredWidth(desiredWidth)
// fitMantissaInDesiredWidth(desiredWidth) round()
// round() mantissa = mantissa and MANTISSA_MASK
// mantissa = mantissa and MANTISSA_MASK }
// }
// /*
// /* * Adjusts the mantissa to desired width for further analysis.
// * Adjusts the mantissa to desired width for further analysis. */
// */ private fun fitMantissaInDesiredWidth(desiredWidth: Int) {
// private fun fitMantissaInDesiredWidth(desiredWidth: Int) { val bitLength = countBitsLength(mantissa)
// val bitLength = countBitsLength(mantissa) if (bitLength > desiredWidth) {
// if (bitLength > desiredWidth) { discardTrailingBits((bitLength - desiredWidth).toLong())
// discardTrailingBits((bitLength - desiredWidth).toLong()) } else {
// } else { mantissa = mantissa shl (desiredWidth - bitLength)
// mantissa = mantissa shl (desiredWidth - bitLength) }
// } }
// }
// /*
// /* * Stores the discarded bits to abandonedNumber.
// * Stores the discarded bits to abandonedNumber. */
// */ private fun discardTrailingBits(num: Long) {
// private fun discardTrailingBits(num: Long) { val mask = (-1L shl num.toInt()).inv()
// val mask = (-1L shl num.toInt()).inv() abandonedNumber += mantissa and mask
// abandonedNumber += mantissa and mask mantissa = mantissa shr num.toInt()
// mantissa = mantissa shr num.toInt() }
// }
// /*
// /* * The value is rounded up or down to the nearest infinitely precise result.
// * The value is rounded up or down to the nearest infinitely precise result. * If the value is exactly halfway between two infinitely precise results,
// * If the value is exactly halfway between two infinitely precise results, * then it should be rounded up to the nearest infinitely precise even.
// * then it should be rounded up to the nearest infinitely precise even. */
// */ private fun round() {
// private fun round() { val result = abandonedNumber.replace("0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$
// val result = abandonedNumber.replace("0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$ val moreThanZero = result.length > 0
// val moreThanZero = result.length > 0
// val lastDiscardedBit = (mantissa and 1L).toInt()
// val lastDiscardedBit = (mantissa and 1L).toInt() mantissa = mantissa shr 1
// mantissa = mantissa shr 1 val tailBitInMantissa = (mantissa and 1L).toInt()
// val tailBitInMantissa = (mantissa and 1L).toInt()
// if (lastDiscardedBit == 1 && (moreThanZero || tailBitInMantissa == 1)) {
// if (lastDiscardedBit == 1 && (moreThanZero || tailBitInMantissa == 1)) { val oldLength = countBitsLength(mantissa)
// val oldLength = countBitsLength(mantissa) mantissa += 1L
// mantissa += 1L val newLength = countBitsLength(mantissa)
// val newLength = countBitsLength(mantissa)
// //Rounds up to exponent when whole bits of mantissa are one-bits.
// //Rounds up to exponent when whole bits of mantissa are one-bits. if (oldLength >= MANTISSA_WIDTH && newLength > oldLength) {
// if (oldLength >= MANTISSA_WIDTH && newLength > oldLength) { checkedAddExponent(1)
// checkedAddExponent(1) }
// } }
// } }
// }
// /*
// /* * Returns the normalized significand after removing the leading zeros.
// * Returns the normalized significand after removing the leading zeros. */
// */ private fun getNormalizedSignificand(strIntegerPart: String, strDecimalPart: String): String {
// private fun getNormalizedSignificand(strIntegerPart: String, strDecimalPart: String): String { var significand = strIntegerPart + strDecimalPart
// var significand = strIntegerPart + strDecimalPart significand = significand.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$//$NON-NLS-2$
// significand = significand.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$//$NON-NLS-2$ if (significand.length == 0) {
// if (significand.length == 0) { significand = "0" //$NON-NLS-1$
// significand = "0" //$NON-NLS-1$ }
// } return significand
// return significand }
// }
// /*
// /* * Calculates the offset between the normalized number and unnormalized
// * Calculates the offset between the normalized number and unnormalized * number. In a normalized representation, significand is represented by the
// * number. In a normalized representation, significand is represented by the * characters "0x1." followed by a lowercase hexadecimal representation of
// * characters "0x1." followed by a lowercase hexadecimal representation of * the rest of the significand as a fraction.
// * the rest of the significand as a fraction. */
// */ private fun getOffset(strIntegerPart: String, strDecimalPart: String): Int {
// private fun getOffset(strIntegerPart: String, strDecimalPart: String): Int { var strIntegerPart = strIntegerPart
// var strIntegerPart = strIntegerPart strIntegerPart = strIntegerPart.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$
// strIntegerPart = strIntegerPart.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$
// // If the Integer part is a nonzero number.
// // If the Integer part is a nonzero number. if (strIntegerPart.length != 0) {
// if (strIntegerPart.length != 0) { val leadingNumber = strIntegerPart.substring(0, 1)
// val leadingNumber = strIntegerPart.substring(0, 1) return (strIntegerPart.length - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1
// return (strIntegerPart.length - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1 }
// }
// // If the Integer part is a zero number.
// // If the Integer part is a zero number. var i = 0
// var i = 0 while (i < strDecimalPart.length && strDecimalPart[i] == '0') {
// while (i < strDecimalPart.length && strDecimalPart[i] == '0') { i++
// i++ }
// } if (i == strDecimalPart.length) {
// if (i == strDecimalPart.length) { return 0
// return 0 }
// } val leadingNumber = strDecimalPart.substring(i, i + 1)
// val leadingNumber = strDecimalPart.substring(i, i + 1) return (-i - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1
// return (-i - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1 }
// }
// fun numberOfLeadingZeros(i: Long): Int {
// fun numberOfLeadingZeros(i: Long): Int { // HD, Figure 5-6
// // HD, Figure 5-6 if (i == 0L)
// if (i == 0L) return 64
// return 64 var n = 1
// var n = 1 var x = (i ushr 32).toInt()
// var x = (i ushr 32).toInt() if (x == 0) {
// if (x == 0) { n += 32
// n += 32 x = i.toInt()
// x = i.toInt() }
// } if (x ushr 16 == 0) {
// if (x ushr 16 == 0) { n += 16
// n += 16 x = x shl 16
// x = x shl 16 }
// } if (x ushr 24 == 0) {
// if (x ushr 24 == 0) { n += 8
// n += 8 x = x shl 8
// x = x shl 8 }
// } if (x ushr 28 == 0) {
// if (x ushr 28 == 0) { n += 4
// n += 4 x = x shl 4
// x = x shl 4 }
// } if (x ushr 30 == 0) {
// if (x ushr 30 == 0) { n += 2
// n += 2 x = x shl 2
// x = x shl 2 }
// } n -= x ushr 31
// n -= x ushr 31 return n
// return n }
// }
// private fun countBitsLength(value: Long) = 64 - numberOfLeadingZeros(value)
// private fun countBitsLength(value: Long): Int {
// val leadingZeros = numberOfLeadingZeros(value) companion object {
// return java.lang.Long.SIZE - leadingZeros
// } private val DOUBLE_EXPONENT_WIDTH = 11
//
// companion object { private val DOUBLE_MANTISSA_WIDTH = 52
//
// private val DOUBLE_EXPONENT_WIDTH = 11 private val FLOAT_EXPONENT_WIDTH = 8
//
// private val DOUBLE_MANTISSA_WIDTH = 52 private val FLOAT_MANTISSA_WIDTH = 23
//
// private val FLOAT_EXPONENT_WIDTH = 8 private val HEX_RADIX = 16
//
// private val FLOAT_MANTISSA_WIDTH = 23 private val MAX_SIGNIFICANT_LENGTH = 15
//
// private val HEX_RADIX = 16 private val HEX_SIGNIFICANT = "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)" //$NON-NLS-1$
//
// private val MAX_SIGNIFICANT_LENGTH = 15 private val BINARY_EXPONENT = "[pP]([+-]?\\d+)" //$NON-NLS-1$
//
// private val HEX_SIGNIFICANT = "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)" //$NON-NLS-1$ private val FLOAT_TYPE_SUFFIX = "[fFdD]?" //$NON-NLS-1$
//
// private val BINARY_EXPONENT = "[pP]([+-]?\\d+)" //$NON-NLS-1$ private val HEX_PATTERN = "[\\x00-\\x20]*([+-]?)$HEX_SIGNIFICANT" + //$NON-NLS-1$
//
// private val FLOAT_TYPE_SUFFIX = "[fFdD]?" //$NON-NLS-1$ BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*" //$NON-NLS-1$
//
// private val HEX_PATTERN = "[\\x00-\\x20]*([+-]?)$HEX_SIGNIFICANT" + //$NON-NLS-1$ private val PATTERN = Regex(HEX_PATTERN)
//
// BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*" //$NON-NLS-1$ /*
// * Parses the hex string to a double number.
// private val PATTERN = Pattern.compile(HEX_PATTERN) */
// fun parseDouble(hexString: String): Double {
// /* val parser = HexStringParser(DOUBLE_EXPONENT_WIDTH,
// * Parses the hex string to a double number. DOUBLE_MANTISSA_WIDTH)
// */ val result = parser.parse(hexString)
// fun parseDouble(hexString: String): Double { return longBitsToDouble(result)
// val parser = HexStringParser(DOUBLE_EXPONENT_WIDTH, }
// DOUBLE_MANTISSA_WIDTH)
// val result = parser.parse(hexString) /*
// return java.lang.Double.longBitsToDouble(result) * Parses the hex string to a float number.
// } */
// fun parseFloat(hexString: String): Float {
// /* val parser = HexStringParser(FLOAT_EXPONENT_WIDTH,
// * Parses the hex string to a float number. FLOAT_MANTISSA_WIDTH)
// */ val result = parser.parse(hexString).toInt()
// fun parseFloat(hexString: String): Float { return intBitsToFloat(result)
// val parser = HexStringParser(FLOAT_EXPONENT_WIDTH, }
// FLOAT_MANTISSA_WIDTH)
// val result = parser.parse(hexString).toInt() /*
// return java.lang.Float.intBitsToFloat(result) * Analyzes the hex string and extracts the sign and digit segments.
// } */
// private fun getSegmentsFromHexString(hexString: String): Array<String> {
// /* val matchResult = PATTERN.matchEntire(hexString)
// * Analyzes the hex string and extracts the sign and digit segments. if (matchResult == null) {
// */ throw NumberFormatException()
// private fun getSegmentsFromHexString(hexString: String): Array<String> { }
// val matcher = PATTERN.matcher(hexString)
// if (!matcher.matches()) { val hexSegments = arrayOf(
// throw NumberFormatException() matchResult.groupValues[1],
// } matchResult.groupValues[2],
// matchResult.groupValues[3]
// val hexSegments = arrayOf( )
// matcher.group(1),
// matcher.group(2), return hexSegments
// matcher.group(3) }
// ) }
// }
// return hexSegments
// }
// }
//}