-
-
Save passsy/8bee0a69c6a33800e44c06e19ff72598 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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