Dart 中的银行家舍入

问题描述 投票:0回答:3

任何人都可以帮助 Dart 中银行家的舍入实现吗

所以我轮到 3 d.p.到最近的 2 d.p.数字 EXCEPT 当数字在中间时它会转到 最接近的偶数

例如

print(1.011.toStringAsFixed(2)); // rounds down to 1.01
print(1.019.toStringAsFixed(2)); // rounds up to 1.02
print(1.015.toStringAsFixed(2)); // rounds down to 1.01 but i want up to 1.02
print(1.025.toStringAsFixed(2)); // rounds down to 1.02
dart double precision
3个回答
3
投票

我有同样的要求,所以我建了一个。

banker_rounding.dart

import 'dart:math';

import 'package:decimal/decimal.dart';

Decimal _getDecimalOfNumber(Decimal number, int fractionDigits) => number - (number.floor());

Decimal _pow10(int powNum) => Decimal.parse(pow(10, powNum).toString());

Decimal _carryLatest(Decimal number) {
  int decimalLength = number.toString().length - 2;
  Decimal offset = _pow10(-decimalLength);
  return number + offset;
}

Decimal bankerRound(Decimal value, int fractionDigits) {
  // integer of number
  Decimal integerOfNumber = value.floor();
  // decimal of number
  Decimal decimalOfNumber = _getDecimalOfNumber(value, fractionDigits);
  // remain flag
  int remainFlag = (decimalOfNumber * _pow10(fractionDigits + 1) % Decimal.fromInt(10)).toInt();
  Decimal finalMultiple = _pow10(fractionDigits);
  Decimal finalDecimalOfNumber = ((decimalOfNumber * finalMultiple).floor() / finalMultiple);
  if (remainFlag <= 4) {
    // do nothing
  } else if (remainFlag >= 6) {
    // carry
    finalDecimalOfNumber = _carryLatest(finalDecimalOfNumber);
  } else {
    // check bottom has number
    bool hasBottom = _getDecimalOfNumber(decimalOfNumber * _pow10(fractionDigits + 1), fractionDigits) != Decimal.zero;
    if (hasBottom) {
      // carry
      finalDecimalOfNumber = _carryLatest(finalDecimalOfNumber);
    } else {
      // check pre remain flag
      int preLastNumber = (decimalOfNumber * _pow10(fractionDigits) % Decimal.fromInt(10)).toInt();
      if (preLastNumber.isOdd) {
        // carry
        finalDecimalOfNumber = _carryLatest(finalDecimalOfNumber);
      } else {
        // do nothing
      }
    }
  }
  return integerOfNumber + finalDecimalOfNumber;
}

0
投票

这里是经过测试的庄家轮到整数的算法。 对于十进制(100% 准确):

import 'dart:math';

import 'package:decimal/decimal.dart';

var _halfDec = Decimal.parse('0.5');
Decimal bankerRoundDecimal(Decimal value) {
  var rounded = value.round();
  if(rounded - value == _halfDec)
    if(value.ceil().toInt() % 2 != 0)
      rounded = value.floor();

  return rounded;
}

对于双人:

double bankerRound(double value) {
  var rounded = value.roundToDouble();
  if(((rounded - value) * 100).round() == 50)
    if(value.ceil() % 2 != 0)
      rounded = value.floorToDouble();

  return rounded;
}

0
投票

我按照这个 docuemnt 并为 Dart 写了另一个。

飞镖

const double ROUNDING_EPSILON = 0.0000001;
double roundHalfEven(double value) {
  if (value < 0.0) return -roundHalfEven(-value);
  double epsilon = ROUNDING_EPSILON;
  double ipart = value.toInt().toDouble();

  // If 'value' is exctly halfway between two integers
  if ((value - (ipart + 0.5)) < epsilon) {
    // If 'ipart' is even then return 'ipart'
    if (ipart % 2.0 < epsilon) {
      return ipart;
    }

    // Else return the nearest even integer
    return (ipart + 0.5).ceilToDouble();
  }

  // Otherwise use the usual round to closest
  // (Either symmetric half-up or half-down will do0
  return value.roundToDouble();
}

测试

import java.math.*

fun main() {
    println(BigDecimal(4.5).setScale(0, RoundingMode.HALF_EVEN)) // 4
    println(BigDecimal(3.5).setScale(0, RoundingMode.HALF_EVEN)) // 4
    println(BigDecimal(4.500001).setScale(0, RoundingMode.HALF_EVEN)) // 5
    println(BigDecimal(3.500001).setScale(0, RoundingMode.HALF_EVEN)) // 4
    println("--------")
    println(BigDecimal(-4.5).setScale(0, RoundingMode.HALF_EVEN)) // -4
    println(BigDecimal(-3.5).setScale(0, RoundingMode.HALF_EVEN)) // -4
    println(BigDecimal(-4.500001).setScale(0, RoundingMode.HALF_EVEN)) // -5
    println(BigDecimal(-3.500001).setScale(0, RoundingMode.HALF_EVEN)) // -4
}
void main() {
  print(roundHalfEven(4.5)); // 4
  print(roundHalfEven(3.5)); // 4
  print(roundHalfEven(4.500001)); // 5
  print(roundHalfEven(3.500001)); // 4
  print('-------');
  print(roundHalfEven(-4.5)); // -4
  print(roundHalfEven(-3.5)); // -4
  print(roundHalfEven(-4.500001)); // -5
  print(roundHalfEven(-3.500001)); // -4
}
© www.soinside.com 2019 - 2024. All rights reserved.