Skip to content
Merged
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 @@ -128,7 +128,7 @@ object FloatingPointDecoders {
def decodeIbmSingleBigEndian(bytes: Array[Byte]): java.lang.Float = {
try {
val IBM32_SIGN_MASK = 0x80000000
val IBM32_EXPONENT_MASK = 0x80000000
val IBM32_EXPONENT_MASK = 0x7F000000
val IBM32_FRACTURE_MASK = 0x00FFFFFF
val IBM32_MS_NIBBLE = 0x00F00000

Expand All @@ -148,7 +148,7 @@ object FloatingPointDecoders {
}
val leadingZeros = ((BIT_COUNT_MAGIC >> (topNibble >> 19)) & 3).toInt
fracture <<= leadingZeros
val convertedExp = exponent + 131 - leadingZeros
val convertedExp = exponent - 131 - leadingZeros

if (convertedExp >=0 && convertedExp < 254) {
val ieee754Int = sign + (convertedExp << 23) + fracture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,52 @@ class FloatingPointDecodersSpec extends AnyWordSpec {
}

"decodeIbmSingleBigEndian()" should {
"decode IBM single precision / big-endian FP numbers" in {
"decode IBM single precision / big-endian FP number 1.0" in {
val bytes = Array[Byte](
0x43.toByte, 0x14.toByte, 0x2E.toByte, 0xFC.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 5.045883f)
0x41.toByte, 0x10.toByte, 0x00.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 1.0f)
}

"decode IBM single precision / big-endian FP number 1234.0" in {
val bytes = Array[Byte](
0x43.toByte, 0x4D.toByte, 0x20.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 1234.0f)
}

"decode IBM single precision / big-endian FP number -1234.0" in {
val bytes = Array[Byte](
0xC3.toByte, 0x4D.toByte, 0x20.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), -1234.0f)
}

"decode IBM single precision / big-endian FP number 4.5" in {
val bytes = Array[Byte](
0x41.toByte, 0x48.toByte, 0x00.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 4.5f)
}

"decode IBM single precision / big-endian FP number -3.75" in {
val bytes = Array[Byte](
0xC1.toByte, 0x3C.toByte, 0x00.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), -3.75f)
}

"decode IBM single precision / big-endian FP number 2.5" in {
val bytes = Array[Byte](
0x41.toByte, 0x28.toByte, 0x00.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 2.5f)
}

"decode IBM single precision / big-endian FP number 0" in {
val bytes = Array[Byte](
0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes), 0f)
}

"decode IBM single precision / big-endian FP number infinity" in {
val bytes = Array[Byte](
0x7F.toByte, 0xFF.toByte, 0xFF.toByte, 0xFF.toByte)
assert(FloatingPointDecoders.decodeIbmSingleBigEndian(bytes).isInfinite)
}
}

Expand All @@ -53,10 +95,40 @@ class FloatingPointDecodersSpec extends AnyWordSpec {
}

"decodeIbmSingleLittleEndian()" should {
"decode IBM single precision / little-endian FP numbers" in {
"decode IBM single precision / little-endian FP number 1.0" in {
val bytes = Array[Byte](
0xFC.toByte, 0x2E.toByte, 0x14.toByte, 0x43.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), 5.045883f)
0x00.toByte, 0x00.toByte, 0x10.toByte, 0x41.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), 1.0f)
}

"decode IBM single precision / little-endian FP number 1234.0" in {
val bytes = Array[Byte](
0x00.toByte, 0x20.toByte, 0x4D.toByte, 0x43.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), 1234.0f)
}

"decode IBM single precision / little-endian FP number -1234.0" in {
val bytes = Array[Byte](
0x00.toByte, 0x20.toByte, 0x4D.toByte, 0xC3.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), -1234.0f)
}

"decode IBM single precision / little-endian FP number 4.5" in {
val bytes = Array[Byte](
0x00.toByte, 0x00.toByte, 0x48.toByte, 0x41.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), 4.5f)
}

"decode IBM single precision / little-endian FP number -3.75" in {
val bytes = Array[Byte](
0x00.toByte, 0x00.toByte, 0x3C.toByte, 0xC1.toByte)
assertFloatEqual(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes), -3.75f)
}

"decode IBM single precision / little-endian FP number infinity" in {
val bytes = Array[Byte](
0xFF.toByte, 0xFF.toByte, 0xFF.toByte, 0x7F.toByte)
assert(FloatingPointDecoders.decodeIbmSingleLittleEndian(bytes).isInfinite)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Test03IbmFloats extends AnyFunSuite with BeforeAndAfterAll with SparkTestB
val f = df.select(col("F")).take(1)(0)(0).asInstanceOf[Float]
val d = df.select(col("D")).take(1)(0)(0).asInstanceOf[Double]

assertFloatEqual(f, 5.045883f)
assertFloatEqual(f, 322.93652f)
assertDoubleEqual(d, 322.936717)
}

Expand All @@ -132,7 +132,7 @@ class Test03IbmFloats extends AnyFunSuite with BeforeAndAfterAll with SparkTestB
val f = df.select(col("F")).take(1)(0)(0).asInstanceOf[Float]
val d = df.select(col("D")).take(1)(0)(0).asInstanceOf[Double]

assertFloatEqual(f, 5.045883f)
assertFloatEqual(f, 322.93652f)
assertDoubleEqual(d, 322.936717)
}

Expand Down
Loading