Skip to content

Instantly share code, notes, and snippets.

@passsy
Forked from jxstxn1/rounding_test.dart
Created May 30, 2025 12:36
Show Gist options
  • Save passsy/8bee0a69c6a33800e44c06e19ff72598 to your computer and use it in GitHub Desktop.
Save passsy/8bee0a69c6a33800e44c06e19ff72598 to your computer and use it in GitHub Desktop.
import 'package:flutter_test/flutter_test.dart';
void main() {
test('1 should round 0.145 to 0.15', () {
const value = 0.145;
final rounded = value.toStringAsFixed(2);
expect(rounded, '0.15'); // actual 0.14
});
test('2 should round 0.145 to 0.15', () {
const value = 0.145;
final rounded = (value * 100).round() / 100;
expect(rounded, 0.15); // actual 0.14
});
test('3 should round 0.145 to 0.15', () {
const value = 0.145;
final rounded = value.toStringWithRoundedDecimals(2);
expect(rounded, 0.15);
});
test('4 should round 1.145 to 0.15', () {
const value = 1.145;
final rounded = value.toStringAsFixed(2);
expect(rounded, '1.15');
});
test('5 should round 1.145 to 1.15', () {
const value = 1.145;
final rounded = (value * 100).round() / 100;
expect(rounded, 1.15);
});
test('6 should round 1.145 to 0.15', () {
const value = 1.145;
final rounded = value.toStringWithRoundedDecimals(2);
expect(rounded, 1.15);
});
}
extension DoubleRounding on double {
/// Rounds this double to [places] decimal places using half-up (>=5) rounding.
double toStringWithRoundedDecimals(int places) {
if (places < 0) {
throw ArgumentError('Decimal places must be non-negative');
}
final str = toString();
if (!str.contains('.')) return this;
final parts = str.split('.');
var integerPart = parts[0];
var fractionPart = parts[1];
// Handle zero decimal places separately
if (places == 0) {
fractionPart = fractionPart.padRight(1, '0');
final shouldRound = int.parse(fractionPart[0]) >= 5;
var intPart = int.parse(integerPart);
intPart += shouldRound ? (this.isNegative ? -1 : 1) : 0;
return intPart.toDouble();
}
// Ensure we have at least places+1 digits to look at
fractionPart = fractionPart.padRight(places + 1, '0');
final digitToRound = int.parse(fractionPart[places]);
var truncated = fractionPart.substring(0, places);
if (digitToRound >= 5) {
// Round up the truncated fraction
final fracInt = BigInt.parse(truncated) + BigInt.one;
if (fracInt.toString().length > truncated.length) {
// Overflow into the integer part (e.g. 0.999 -> 1.00)
final intPart = int.parse(integerPart) + (this.isNegative ? -1 : 1);
integerPart = intPart.toString();
truncated = ''.padLeft(places, '0');
} else {
truncated = fracInt.toString().padLeft(places, '0');
}
}
final resultStr = '$integerPart.$truncated';
return double.parse(resultStr);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment