summaryrefslogblamecommitdiff
path: root/examples/scala-js/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FloatTest.scala
blob: e45a34a2b9b7fb78e7abc854f0b5942a9bce05e0 (plain) (tree)




























































































































































































































                                                                                               
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js Test Suite        **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2013, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-js.org/       **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */
package scala.scalajs.testsuite.javalib

import org.scalajs.jasminetest.JasmineTest
import scala.scalajs.js

import java.lang.{Float => JFloat}

import scala.util.Try

object FloatTest extends JasmineTest {

  describe("java.lang.Float") {

    it("should provide proper `equals`") {
      expect(Float.box(0.0f) == Float.box(-0.0f)).toBeTruthy
      expect(Float.box(Float.NaN) == Float.box(Float.NaN)).toBeTruthy
    }

    it("hashCode") {
      def hashCodeNotInlined(x: Any): Int = {
        var y = x // do not inline
        y.hashCode
      }

      def test(x: Float, expected: Int): Unit = {
        expect(x.hashCode).toEqual(expected)
        expect(hashCodeNotInlined(x)).toEqual(expected)
      }

      test(0.0f, 0)
      test(-0.0f, 0)
      test(1234.0f, 1234)
      test(1.5f, 1073217536)
      test(-54f, -54)

      test(Float.MinPositiveValue, 916455424)
      test(Float.MinValue, 670040063)
      test(Float.MaxValue, -1477443585)

      test(Float.NaN, 2146959360)
      test(Float.PositiveInfinity, 2146435072)
      test(Float.NegativeInfinity, -1048576)
    }

    it("should provide `toString` with integer values when an integer") {
      expect(0.0f.toString).toEqual("0")
      expect(-0.0f.toString).toEqual("0")
      expect(Float.NaN.toString).toEqual("NaN")
      expect(Float.PositiveInfinity.toString).toEqual("Infinity")
      expect(Float.NegativeInfinity.toString).toEqual("-Infinity")
      expect(5.0f.toString).toEqual("5")
      expect(-5.0f.toString).toEqual("-5")

      // We need to explicitly cut the string here, since floats are
      // represented by doubles (but the literal is emitted as
      // float). Therefore there may be some imprecision. This is
      // documented as semantic difference.
      expect(1.2f.toString.substring(0,3)).toEqual("1.2")
    }

    it("should parse strings") {
      expect("0.0".toFloat).toEqual(0.0f)
      expect("NaN".toFloat.isNaN).toBeTruthy
      expect(Try("asdf".toFloat).isFailure).toBeTruthy

      def test(s: String, v: Float): Unit = {
        expect(JFloat.parseFloat(s)).toBeCloseTo(v)
        expect(JFloat.valueOf(s).floatValue()).toBeCloseTo(v)
        expect(new JFloat(s).floatValue()).toBeCloseTo(v)
      }

      test("0", 0.0f)
      test("5.3", 5.3f)
      test("127e2", 12700.0f)
      test("127E-2", 1.27f)
      test("1E+1", 10f)
      test("-123.4", -123.4f)
      test("65432.1", 65432.10f)
      test("-87654.321", -87654.321f)
      test("+.3f", 0.3f)
    }

    it("should reject invalid strings when parsing") {
      def test(s: String): Unit =
        expect(() => JFloat.parseFloat(s)).toThrow

      test("4.3.5")
      test("4e3.5")
      test("hello world")
      test("--4")
      test("4E-3.2")
    }

    it("should provide `compareTo`") {
      def compare(x: Float, y: Float): Int =
        new JFloat(x).compareTo(new JFloat(y))

      expect(compare(0.0f, 5.5f)).toBeLessThan(0)
      expect(compare(10.5f, 10.2f)).toBeGreaterThan(0)
      expect(compare(-2.1f, -1.0f)).toBeLessThan(0)
      expect(compare(3.14f, 3.14f)).toEqual(0)

      // From compareTo's point of view, NaN is equal to NaN
      expect(compare(Float.NaN, Float.NaN)).toEqual(0)
    }

    it("should be a Comparable") {
      def compare(x: Any, y: Any): Int =
        x.asInstanceOf[Comparable[Any]].compareTo(y)

      expect(compare(0.0f, 5.5f)).toBeLessThan(0)
      expect(compare(10.5f, 10.2f)).toBeGreaterThan(0)
      expect(compare(-2.1f, -1.0f)).toBeLessThan(0)
      expect(compare(3.14f, 3.14f)).toEqual(0)

      // From compareTo's point of view, NaN is equal to NaN
      expect(compare(Float.NaN, Float.NaN)).toEqual(0)
    }

    it("should provide isInfinite - #515") {
      expect(Float.PositiveInfinity.isInfinite).toBeTruthy
      expect(Float.NegativeInfinity.isInfinite).toBeTruthy
      expect((1f/0).isInfinite).toBeTruthy
      expect((-1f/0).isInfinite).toBeTruthy
      expect(0f.isInfinite).toBeFalsy
    }

    it("isNaN") {
      def f(v: Float): Boolean = {
        var v2 = v // do not inline
        v2.isNaN
      }

      expect(f(Float.NaN)).toBeTruthy

      expect(f(Float.PositiveInfinity)).toBeFalsy
      expect(f(Float.NegativeInfinity)).toBeFalsy
      expect(f(1f / 0)).toBeFalsy
      expect(f(-1f / 0)).toBeFalsy
      expect(f(0f)).toBeFalsy
      expect(f(3f)).toBeFalsy
      expect(f(-1.5f)).toBeFalsy
    }

    it("intBitsToFloat") {
      def isZero(v: Float, neg: Boolean): Boolean = {
        (v == 0.0f) && (1 / v == (
            if (neg) Float.NegativeInfinity
            else Float.PositiveInfinity))
      }

      import JFloat.{intBitsToFloat => f}

      // Specials
      expect(f(0x7f800000)).toEqual(Float.PositiveInfinity)
      expect(f(0xff800000)).toEqual(Float.NegativeInfinity)
      expect(isZero(f(0x00000000), false)).toBeTruthy
      expect(isZero(f(0x80000000), true)).toBeTruthy
      expect(f(0x7fc00000).isNaN).toBeTruthy // canonical NaN

      // Non-canonical NaNs
      expect(f(0x7f800001).isNaN).toBeTruthy // smallest positive NaN
      expect(f(0x7f915ab5).isNaN).toBeTruthy // an arbitrary positive NaN
      expect(f(0x7fffffff).isNaN).toBeTruthy // largest positive NaN
      expect(f(0xff800001).isNaN).toBeTruthy // smallest negative NaN
      expect(f(0xff915ab5).isNaN).toBeTruthy // an arbitrary negative NaN
      expect(f(0xffffffff).isNaN).toBeTruthy // largest negative NaN

      // Normal forms
      expect(f(0x00800000)).toEqual(1.17549435e-38f)  // smallest pos normal form
      expect(f(0x7f7fffff)).toEqual(3.4028234e38f)    // largest pos normal form
      expect(f(0x4d124568)).toEqual(1.53376384e8f)    // an arbitrary pos normal form
      expect(f(0x80800000)).toEqual(-1.17549435e-38f) // smallest neg normal form
      expect(f(0xff7fffff)).toEqual(-3.4028234e38f)   // largest neg normal form
      expect(f(0xcd124568)).toEqual(-1.53376384e8f)   // an arbitrary neg normal form

      // Subnormal forms
      expect(f(0x00000001)).toEqual(Float.MinPositiveValue)  // smallest pos subnormal form
      expect(f(0x007fffff)).toEqual(1.1754942e-38f)          // largest pos subnormal form
      expect(f(0x007c5d44)).toEqual(1.1421059e-38f)          // an arbitrary pos subnormal form
      expect(f(0x80000001)).toEqual(-Float.MinPositiveValue) // smallest neg subnormal form
      expect(f(0x807fffff)).toEqual(-1.1754942e-38f)         // largest neg subnormal form
      expect(f(0x807c5d44)).toEqual(-1.1421059e-38f)         // an arbitrary neg subnormal form
    }

    it("floatToIntBits") {
      import JFloat.{floatToIntBits => f}

      // Specials
      expect(f(Float.PositiveInfinity)).toEqual(0x7f800000)
      expect(f(Float.NegativeInfinity)).toEqual(0xff800000)
      expect(f(0.0f)).toEqual(0x00000000)
      expect(f(-0.0f)).toEqual(0x80000000)
      expect(f(Float.NaN)).toEqual(0x7fc00000) // canonical NaN

      // Normal forms
      expect(f(1.17549435e-38f)).toEqual(0x00800000)  // smallest pos normal form
      expect(f(3.4028234e38f)).toEqual(0x7f7fffff)    // largest pos normal form
      expect(f(1.53376384e8f)).toEqual(0x4d124568)    // an arbitrary pos normal form
      expect(f(-1.17549435e-38f)).toEqual(0x80800000) // smallest neg normal form
      expect(f(-3.4028234e38f)).toEqual(0xff7fffff)   // largest neg normal form
      expect(f(-1.53376384e8f)).toEqual(0xcd124568)   // an arbitrary neg normal form

      // Subnormal forms
      expect(f(Float.MinPositiveValue)).toEqual(0x00000001)  // smallest pos subnormal form
      expect(f(1.1754942e-38f)).toEqual(0x007fffff)          // largest pos subnormal form
      expect(f(1.1421059e-38f)).toEqual(0x007c5d44)          // an arbitrary pos subnormal form
      expect(f(-Float.MinPositiveValue)).toEqual(0x80000001) // smallest neg subnormal form
      expect(f(-1.1754942e-38f)).toEqual(0x807fffff)         // largest neg subnormal form
      expect(f(-1.1421059e-38f)).toEqual(0x807c5d44)         // an arbitrary neg subnormal form
    }

  }
}