mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:30:32 +00:00
84e3c8b50f
Closes https://github.com/dart-lang/sdk/pull/50920 GitOrigin-RevId: fa87531bd0f52b69485c9d02ff9e44a4a29c6a91 Change-Id: I0ae8574a5b77087895e004079f221201bb550cf3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278535 Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Thomas <athom@google.com> Commit-Queue: Alexander Thomas <athom@google.com>
255 lines
9.8 KiB
Dart
255 lines
9.8 KiB
Dart
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library math_test;
|
|
|
|
import "package:expect/expect.dart";
|
|
import 'dart:math';
|
|
|
|
class MathTest {
|
|
static void testConstants() {
|
|
// Source for mathematical constants is Wolfram Alpha.
|
|
Expect.equals(
|
|
2.7182818284590452353602874713526624977572470936999595749669, e);
|
|
Expect.equals(
|
|
2.3025850929940456840179914546843642076011014886287729760333, ln10);
|
|
Expect.equals(
|
|
0.6931471805599453094172321214581765680755001343602552541206, ln2);
|
|
Expect.equals(
|
|
1.4426950408889634073599246810018921374266459541529859341354, log2e);
|
|
Expect.equals(
|
|
0.4342944819032518276511289189166050822943970058036665661144, log10e);
|
|
Expect.equals(
|
|
3.1415926535897932384626433832795028841971693993751058209749, pi);
|
|
Expect.equals(
|
|
0.7071067811865475244008443621048490392848359376884740365883, sqrt1_2);
|
|
Expect.equals(
|
|
1.4142135623730950488016887242096980785696718753769480731766, sqrt2);
|
|
}
|
|
|
|
static checkClose(double a, double b, EPSILON) {
|
|
Expect.equals(true, a - EPSILON <= b);
|
|
Expect.equals(true, b <= a + EPSILON);
|
|
}
|
|
|
|
static void testSin() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, sin(0.0), EPSILON);
|
|
checkClose(0.0, sin(pi), EPSILON);
|
|
checkClose(0.0, sin(2.0 * pi), EPSILON);
|
|
checkClose(1.0, sin(pi / 2.0), EPSILON);
|
|
checkClose(-1.0, sin(pi * (3.0 / 2.0)), EPSILON);
|
|
}
|
|
|
|
static void testCos() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(1.0, cos(0.0), EPSILON);
|
|
checkClose(-1.0, cos(pi), EPSILON);
|
|
checkClose(1.0, cos(2.0 * pi), EPSILON);
|
|
checkClose(0.0, cos(pi / 2.0), EPSILON);
|
|
checkClose(0.0, cos(pi * (3.0 / 2.0)), EPSILON);
|
|
}
|
|
|
|
static void testTan() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, tan(0.0), EPSILON);
|
|
checkClose(0.0, tan(pi), EPSILON);
|
|
checkClose(0.0, tan(2.0 * pi), EPSILON);
|
|
checkClose(1.0, tan(pi / 4.0), EPSILON);
|
|
}
|
|
|
|
static void testAsin() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, asin(0.0), EPSILON);
|
|
checkClose(pi / 2.0, asin(1.0), EPSILON);
|
|
checkClose(-pi / 2.0, asin(-1.0), EPSILON);
|
|
}
|
|
|
|
static void testAcos() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, acos(1.0), EPSILON);
|
|
checkClose(pi, acos(-1.0), EPSILON);
|
|
checkClose(pi / 2.0, acos(0.0), EPSILON);
|
|
}
|
|
|
|
static void testAtan() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, atan(0.0), EPSILON);
|
|
checkClose(pi / 4.0, atan(1.0), EPSILON);
|
|
checkClose(-pi / 4.0, atan(-1.0), EPSILON);
|
|
}
|
|
|
|
static void testAtan2() {
|
|
// Given the imprecision of pi we can't expect better results than this.
|
|
final double EPSILON = 1e-15;
|
|
checkClose(0.0, atan2(0.0, 5.0), EPSILON);
|
|
checkClose(pi / 4.0, atan2(2.0, 2.0), EPSILON);
|
|
checkClose(3 * pi / 4.0, atan2(0.5, -0.5), EPSILON);
|
|
checkClose(-3 * pi / 4.0, atan2(-2.5, -2.5), EPSILON);
|
|
}
|
|
|
|
static checkVeryClose(double a, double b) {
|
|
// We find a ulp (unit in the last place) by shifting the original number
|
|
// to the right. This only works if we are not too close to infinity or if
|
|
// we work with denormals.
|
|
// We special case or 0.0, but not for infinity.
|
|
if (a == 0.0) {
|
|
final minimalDouble = 4.9406564584124654e-324;
|
|
Expect.equals(true, b.abs() <= minimalDouble);
|
|
return;
|
|
}
|
|
if (b == 0.0) {
|
|
// No need to look if they are close. Otherwise the check for 'a' above
|
|
// would have triggered.
|
|
Expect.equals(a, b);
|
|
}
|
|
final double shiftRightBy52 = 2.220446049250313080847263336181640625e-16;
|
|
final double shiftedA = (a * shiftRightBy52).abs();
|
|
// Compared to 'a', 'shiftedA' is now ~1-2 ulp.
|
|
|
|
final double limitLow = a - shiftedA;
|
|
final double limitHigh = a + shiftedA;
|
|
Expect.equals(false, a == limitLow);
|
|
Expect.equals(false, a == limitHigh);
|
|
Expect.equals(true, limitLow <= b);
|
|
Expect.equals(true, b <= limitHigh);
|
|
}
|
|
|
|
static void testSqrt() {
|
|
checkVeryClose(2.0, sqrt(4.0));
|
|
checkVeryClose(sqrt2, sqrt(2.0));
|
|
checkVeryClose(sqrt1_2, sqrt(0.5));
|
|
checkVeryClose(1e50, sqrt(1e100));
|
|
checkVeryClose(1.1111111061110855443054405046358901279277111935183977e56,
|
|
sqrt(12345678901234e99));
|
|
}
|
|
|
|
static void testExp() {
|
|
checkVeryClose(e, exp(1.0));
|
|
final EPSILON = 1e-15;
|
|
checkClose(10.0, exp(ln10), EPSILON);
|
|
checkClose(2.0, exp(ln2), EPSILON);
|
|
}
|
|
|
|
static void testLog() {
|
|
// Even though E is imprecise, it is good enough to get really close to 1.
|
|
// We still provide an epsilon.
|
|
checkClose(1.0, log(e), 1e-16);
|
|
checkVeryClose(ln10, log(10.0));
|
|
checkVeryClose(ln2, log(2.0));
|
|
}
|
|
|
|
static bool parseIntThrowsFormatException(str) {
|
|
try {
|
|
int.parse(str);
|
|
return false;
|
|
} on FormatException catch (e) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static void testParseInt() {
|
|
Expect.equals(499, int.parse("499"));
|
|
Expect.equals(499, int.parse("+499"));
|
|
Expect.equals(-499, int.parse("-499"));
|
|
Expect.equals(499, int.parse(" 499 "));
|
|
Expect.equals(499, int.parse(" +499 "));
|
|
Expect.equals(-499, int.parse(" -499 "));
|
|
Expect.equals(0, int.parse("0"));
|
|
Expect.equals(0, int.parse("+0"));
|
|
Expect.equals(0, int.parse("-0"));
|
|
Expect.equals(0, int.parse(" 0 "));
|
|
Expect.equals(0, int.parse(" +0 "));
|
|
Expect.equals(0, int.parse(" -0 "));
|
|
Expect.equals(0x1234567890, int.parse("0x1234567890"));
|
|
Expect.equals(-0x1234567890, int.parse("-0x1234567890"));
|
|
Expect.equals(0x1234567890, int.parse(" 0x1234567890 "));
|
|
Expect.equals(-0x1234567890, int.parse(" -0x1234567890 "));
|
|
Expect.equals(256, int.parse("0x100"));
|
|
Expect.equals(-256, int.parse("-0x100"));
|
|
Expect.equals(256, int.parse(" 0x100 "));
|
|
Expect.equals(-256, int.parse(" -0x100 "));
|
|
Expect.equals(0xabcdef, int.parse("0xabcdef"));
|
|
Expect.equals(0xABCDEF, int.parse("0xABCDEF"));
|
|
Expect.equals(0xabcdef, int.parse("0xabCDEf"));
|
|
Expect.equals(-0xabcdef, int.parse("-0xabcdef"));
|
|
Expect.equals(-0xABCDEF, int.parse("-0xABCDEF"));
|
|
Expect.equals(0xabcdef, int.parse(" 0xabcdef "));
|
|
Expect.equals(0xABCDEF, int.parse(" 0xABCDEF "));
|
|
Expect.equals(-0xabcdef, int.parse(" -0xabcdef "));
|
|
Expect.equals(-0xABCDEF, int.parse(" -0xABCDEF "));
|
|
Expect.equals(0xabcdef, int.parse("0x00000abcdef"));
|
|
Expect.equals(0xABCDEF, int.parse("0x00000ABCDEF"));
|
|
Expect.equals(-0xabcdef, int.parse("-0x00000abcdef"));
|
|
Expect.equals(-0xABCDEF, int.parse("-0x00000ABCDEF"));
|
|
Expect.equals(0xabcdef, int.parse(" 0x00000abcdef "));
|
|
Expect.equals(0xABCDEF, int.parse(" 0x00000ABCDEF "));
|
|
Expect.equals(-0xabcdef, int.parse(" -0x00000abcdef "));
|
|
Expect.equals(-0xABCDEF, int.parse(" -0x00000ABCDEF "));
|
|
Expect.equals(10, int.parse("010"));
|
|
Expect.equals(-10, int.parse("-010"));
|
|
Expect.equals(10, int.parse(" 010 "));
|
|
Expect.equals(-10, int.parse(" -010 "));
|
|
Expect.equals(9, int.parse("09"));
|
|
Expect.equals(9, int.parse(" 09 "));
|
|
Expect.equals(-9, int.parse("-09"));
|
|
Expect.equals(0x1234567890, int.parse("+0x1234567890"));
|
|
Expect.equals(0x1234567890, int.parse(" +0x1234567890 "));
|
|
Expect.equals(0x100, int.parse("+0x100"));
|
|
Expect.equals(0x100, int.parse(" +0x100 "));
|
|
Expect.equals(true, parseIntThrowsFormatException("1b"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" 1b "));
|
|
Expect.equals(true, parseIntThrowsFormatException(" 1 b "));
|
|
Expect.equals(true, parseIntThrowsFormatException("1e2"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" 1e2 "));
|
|
Expect.equals(true, parseIntThrowsFormatException("00x12"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" 00x12 "));
|
|
Expect.equals(true, parseIntThrowsFormatException("-1b"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" -1b "));
|
|
Expect.equals(true, parseIntThrowsFormatException(" -1 b "));
|
|
Expect.equals(true, parseIntThrowsFormatException("-1e2"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" -1e2 "));
|
|
Expect.equals(true, parseIntThrowsFormatException("-00x12"));
|
|
Expect.equals(true, parseIntThrowsFormatException(" -00x12 "));
|
|
Expect.equals(true, parseIntThrowsFormatException(" -00x12 "));
|
|
Expect.equals(true, parseIntThrowsFormatException("0x0x12"));
|
|
Expect.equals(true, parseIntThrowsFormatException("0.1"));
|
|
Expect.equals(true, parseIntThrowsFormatException("0x3.1"));
|
|
Expect.equals(true, parseIntThrowsFormatException("5."));
|
|
Expect.equals(true, parseIntThrowsFormatException("+-5"));
|
|
Expect.equals(true, parseIntThrowsFormatException("-+5"));
|
|
Expect.equals(true, parseIntThrowsFormatException("--5"));
|
|
Expect.equals(true, parseIntThrowsFormatException("++5"));
|
|
Expect.equals(true, parseIntThrowsFormatException("+ 5"));
|
|
Expect.equals(true, parseIntThrowsFormatException("- 5"));
|
|
Expect.equals(true, parseIntThrowsFormatException(""));
|
|
Expect.equals(true, parseIntThrowsFormatException(" "));
|
|
}
|
|
|
|
static testMain() {
|
|
testConstants();
|
|
testSin();
|
|
testCos();
|
|
testTan();
|
|
testAsin();
|
|
testAcos();
|
|
testAtan();
|
|
testAtan2();
|
|
testSqrt();
|
|
testLog();
|
|
testExp();
|
|
testParseInt();
|
|
}
|
|
}
|
|
|
|
main() {
|
|
MathTest.testMain();
|
|
}
|