最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - How do I implement in Dart methods that receive doubles and give similar results to Java Math nextUp() and nextDown()

programmeradmin0浏览0评论

In Java there are nextUp() and nextDown() methods that return the next double (up or down) representable by the system.

It usually works on the binary representation of the double, just incrementing or decrementing a bit and getting back the double.

How can I implement methods that give the same results in dart?

One implementation of these methods in Java can be seen here: .base/share/classes/java/lang/Math.java

One explanation of some details of these methods can be seen here: /

In Java there are nextUp() and nextDown() methods that return the next double (up or down) representable by the system.

It usually works on the binary representation of the double, just incrementing or decrementing a bit and getting back the double.

How can I implement methods that give the same results in dart?

One implementation of these methods in Java can be seen here: https://github/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Math.java

One explanation of some details of these methods can be seen here: https://www.geeksfeeks./java-math-nextup-method-examples/

Share Improve this question asked Feb 3 at 20:45 RseveroRsevero 3304 silver badges14 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Heavily inspired by dart_numerics code:


    static double nextUp(double x) {
        if ((x.isNaN) || (x == double.infinity)) {
          return x;
        }
    
        if (x == double.negativeInfinity) {
          return -double.maxFinite;
        }
    
        if ((x == 0.0) || (x == -0.0)) {
          return double.minPositive;
        }

        int signed64 = doubleToInt64Bits(x);
    
        if (x > 0.0) {
          signed64++;
        } else {
          signed64--;
        }
    
        return int64BitsToDouble(signed64);
      }
    
      static double nextDown(double x) {
        if ((x.isNaN) || (x == double.negativeInfinity)) {
          return x;
        }
    
        if (x == double.infinity) {
          return double.maxFinite;
        }
    
        if ((x == 0.0) || (x == -0.0)) {
          return -double.minPositive;
        }
    
        int signed64 = doubleToInt64Bits(x);
    
        if (x > 0.0) {
          signed64--;
        } else {
          signed64++;
        }
    
        return int64BitsToDouble(signed64);
      }
    
      static int doubleToInt64Bits(double value) {
        ByteData bytes = ByteData(8);
        bytes.setFloat64(0, value);
        return bytes.getInt64(0);
      }
    
      static double int64BitsToDouble(int value) {
        ByteData bytes = ByteData(8);
        bytes.setInt64(0, value);
        return bytes.getFloat64(0);
      }

As a bonus I separated the doubleToInt64Bits() method so anybody wanting to work on a binary representation of doubles in Dart can use it in conjunction to int64BitsToDouble() already provided by dart_numerics.

As an extension to the other answer, here is a version without ByteData.getInt64 that will work on dart2js and Flutter Web. (The problem is that ByteData.getInt64 doesn't work when the Dart is compiled to Javascript.)

double nextUp(double x) {
  if ((x.isNaN) || (x == double.infinity)) {
    return x;
  }

  if (x == double.negativeInfinity) {
    return -double.maxFinite;
  }

  if ((x == 0.0) || (x == -0.0)) {
    return double.minPositive;
  }

  var (sign, exponent, precision) = doubleToComponents(x);

  if (x > 0.0) {
    precision++;
  } else {
    precision--;
  }

  return componentsToDouble(sign, exponent, precision);
}

double nextDown(double x) {
  if ((x.isNaN) || (x == double.negativeInfinity)) {
    return x;
  }

  if (x == double.infinity) {
    return double.maxFinite;
  }

  if ((x == 0.0) || (x == -0.0)) {
    return -double.minPositive;
  }

  var (sign, exponent, precision) = doubleToComponents(x);

  if (x > 0.0) {
    precision--;
  } else {
    precision++;
  }

  return componentsToDouble(sign, exponent, precision);
}

(int, int, int) doubleToComponents(double value) {
  ByteData bytes = ByteData(8);
  bytes.setFloat64(0, value);
  final sign = bytes.getUint8(0) >> 7;
  final exp = ((bytes.getUint8(0) & 0x7F) << 4) | ((bytes.getUint8(1) >> 4));
  final prec = ((bytes.getUint8(1) & 0x0F) << 48) + (bytes.getUint32(2) << 16) + (bytes.getUint16(6));
  return (sign, exp, prec);
}

double componentsToDouble(int sign, int exponent, int precision) {
  ByteData bytes = ByteData(8);
  bytes.setUint8(0, (sign << 7) + (exponent >> 4));
  bytes.setUint8(1, ((exponent & 0xF) << 4) + (precision >> 48));
  bytes.setUint32(2, (precision >> 16) & 0xFFFFFFFF);
  bytes.setUint16(6, precision & 0xFFFF);
  return bytes.getFloat64(0);
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论