Last active
October 15, 2021 16:09
-
-
Save alexcmgit/bd92fc5ee05e8595e66b14e9c6e195e5 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 'dart:math'; | |
String _roundTo(num value, int decimals, | |
{bool floor = true, bool round = false, bool ceil = false}) { | |
assert(floor || round || ceil); | |
final sign = value >= 0 ? 1 : -1; | |
final current = ((value * pow(10, decimals)) + (sign * 0.001)); | |
final base = (() { | |
if (floor) return current.floor(); | |
if (round) return current.round(); | |
if (ceil) return current.ceil(); | |
})()!; | |
return (base / pow(10, decimals)).toStringAsFixed(decimals); | |
} | |
String _format( | |
num value, | |
double base, { | |
bool ceil = true, | |
bool floor = false, | |
bool round = false, | |
int fractionDigits = 2, | |
bool forceFraction = false, | |
}) { | |
if (value < base) return '$value'; | |
final minPostfix = base / pow(10, fractionDigits); | |
final before = value ~/ base; | |
final rest = value - before * base; | |
final rounded = _roundTo( | |
rest / base, | |
fractionDigits, | |
ceil: ceil, | |
floor: floor, | |
round: round, | |
); | |
final decimalValue = '$rounded'.substring(2); | |
final after = forceFraction || rest >= minPostfix | |
? '.${decimalValue.padRight(fractionDigits, '0')}' | |
: ''; | |
return '$before$after'; | |
} | |
String formatIt( | |
num value, { | |
int fractionDigits = 2, | |
bool floor = true, | |
bool round = false, | |
bool ceil = false, | |
bool forceFraction = false, | |
}) { | |
const bases = [1e15, 1e12, 1e9, 1e6, 1e3]; | |
const postfixes = ['Q', 'T', 'B', 'M', 'K']; | |
if (value < bases.last) return '$value'; | |
for (var i = 0; i < bases.length; i++) { | |
final base = bases[i], postfix = postfixes[i]; | |
if (value >= base) { | |
final formatted = _format( | |
value, | |
base, | |
ceil: ceil, | |
floor: floor, | |
round: round, | |
fractionDigits: fractionDigits, | |
forceFraction: forceFraction, | |
); | |
return '$formatted$postfix'; | |
} | |
} | |
throw Exception('We can\'t format $value. Max allowed value: ${bases.first}'); | |
} | |
/// ====================================================== | |
/// format_number_test.dart | |
/// ====================================================== | |
import 'package:test/test.dart'; | |
void main() { | |
group('[formatNumber] method', () { | |
test( | |
'only int | Fraction Digits = 2 | floor = true | round = false | ceil = false', | |
() { | |
final useCases = [ | |
[1000, '1K'], | |
[10001, '10K'], | |
[1000000, '1M'], | |
[1000001, '1M'], | |
[34567677, '34.56M'], | |
[48957634, '48.95M'], | |
[9435643565, '9.43B'], | |
[10100, '10.10K'], | |
[1100000, '1.10M'], | |
[1111111, '1.11M'], | |
[10011, '10.01K'], | |
[1010000, '1.01M'], | |
[123456789, '123.45M'], | |
[56897845, '56.89M'], | |
[10100, '10.10K'], | |
[999, '999'], | |
[1, '1'], | |
[10, '10'], | |
[150, '150'], | |
[1234567, '1.23M'], | |
]; | |
for (var i = 0; i < useCases.length; i++) { | |
expect(formatIt(useCases[i][0] as num), useCases[i][1] as String); | |
} | |
}); | |
test( | |
'only int | Fraction Digits = 1 | floor = true | round = false | ceil = false', | |
() { | |
final useCases = [ | |
[1000, '1K'], | |
[10001, '10K'], | |
[1000000, '1M'], | |
[1000001, '1M'], | |
[34567677, '34.5M'], | |
[48957634, '48.9M'], | |
[9435643565, '9.4B'], | |
[10100, '10.1K'], | |
[1100000, '1.1M'], | |
[1111111, '1.1M'], | |
[10011, '10K'], | |
[1010000, '1M'], | |
[123456789, '123.4M'], | |
[56897845, '56.8M'], | |
[10100, '10.1K'], | |
[999, '999'], | |
[1, '1'], | |
[10, '10'], | |
[150, '150'], | |
[1234567, '1.2M'], | |
]; | |
for (var i = 0; i < useCases.length; i++) { | |
expect( | |
formatIt( | |
useCases[i][0] as num, | |
fractionDigits: 1, | |
), | |
useCases[i][1] as String, | |
); | |
} | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment