how to round up a double value in flutter - dart

Is there anyway to round up a double value?
I want result always rounded up.
int offSet = (totalRecords / 10).round();

It's ceil:
Returns the least integer no smaller than this.
int offSet = (totalRecords / 10).ceil();

Here I'm rounding it to the next double or to next 0.5;
Sample: If its 6.6 then rount to 7.0. If its 6.2, then round to 6.5. See code bellow:
String arredonde(String n) {
final List x = n.split('.'); //break in to a list
if (x.length > 1) { //if its 0, then its already a rounded number or integer
int fstNmbr = int.parse(x[0]);
final int lstNmbrs = int.parse(x[1]);
if (lstNmbrs > 5) {
fstNmbr = fstNmbr + 1;
final String finalNumber = fstNmbr.toStringAsFixed(1);
return finalNumber;
} else {
if (lstNmbrs != 0) {
final double finalNumber = fstNmbr + 0.5;
return finalNumber.toStringAsFixed(1);
} else {
return n;
}
}
} else {
return n;
}
}

try with
num.parse((totalRecords / 10).toStringAsFixed(3))
if you want 3 decimal

Now you have something like you want. I choose sup to 5 to round up, you can change if you want
num offSet = (totalRecords / 10);
var eval = offSet.toStringAsFixed(1).split('.');
var res =
int.parse(eval[1]) > 5 ? int.parse(eval[0]) + 1 : int.parse(eval[0]);
print(res);

Related

I'm trying to convert integer to roman in Dart

I'm new to Dart. I was trying to convert integer to roman. But It returns nothing. Can you guys help me? here is my code sample.
this code is from the Leetcode problem section.
class Solution {
String intToRoman(int num) {
List<int> numbers = [1,4,5,9,10,40,50,90,100,400,500,900,1000];
List<String> romans = ["I","IV","V","IX","X","XL","L","XC","C","CD","D","CM", "M"];
int index = romans.length - 1;
String roman = '';
for(num >0;numbers[index]<=num;){
roman += romans[index];
num -= numbers[index];
index -= 1;
}
return roman;
}
}
just change a little bit on the logic
.try on dartpad: https://dartpad.dev/?id
void main() {
print (intToRoman(30)); // result: XXX
}
String intToRoman(int num) {
List<int> numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
List<String> romans = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
String roman = '';
for (int i = 0; i < numbers.length; i++) {
while (num >= numbers[i]) {
roman += romans[i];
num -= numbers[i];
}
}
return roman;
}
This solution is based on Wiki:
class Solution {
/// digit: 3=Thousands(10³), 2=Hundreds(10²), 1=Tens(10), 0=Units(1)
/// Range for roman numerals: 1...3999
static final romanNumerals = <int,Map<int,String>>{
1 : {3:'M', 2:'C', 1:'X', 0:'I'},
2 : {3:'MM', 2:'CC', 1:'XX', 0:'II'},
3 : {3:'MMM', 2:'CCC', 1:'XXX', 0:'III'},
4 : {2:'CD', 1:'XL', 0:'IV'},
5 : {2:'D', 1:'L', 0:'V'},
6 : {2:'DC', 1:'LX', 0:'VI'},
7 : {2:'DCC', 1:'LXX', 0:'VII'},
8 : {2:'DCCC', 1:'LXXX', 0:'VIII'},
9 : {2:'CM', 1:'XC', 0:'IX'},
};
/* ---------------------------------------------------------------------------- */
Solution();
/* ---------------------------------------------------------------------------- */
String intToRoman(int number) {
if (number < 1 || number >= 4000) return '';
var list = number.toString().split('').map(int.parse).toList();
var buffer = StringBuffer();
final len = list.length;
for (var i = 0; i < len; i++) {
var digit = list[i];
if (digit == 0) continue;
buffer.write(romanNumerals[digit]![len - 1 - i]);
}
return buffer.toString();
}
/* ---------------------------------------------------------------------------- */
void intToRoman2(int number) {
print(intToRoman(number));
}
}
void main(List<String> args) {
Solution()
..intToRoman2(3)
..intToRoman2(58)
..intToRoman2(1994)
;
}
Output:
III
LVIII
MCMXCIV
This code was already sent to LeetCode with the following results:
Runtime: 1130 ms, faster than 27.96% of Dart online submissions for Integer to Roman.
Memory Usage: 150.5 MB, less than 44.09% of Dart online submissions for Integer to Roman.
why not use the simple way?
I use this extension to convert english numbers to persian numbers
extension StringExtensions on String {
String persianNumber() {
String number = this;
number = number.replaceAll("1", "۱");
number = number.replaceAll("2", "۲");
number = number.replaceAll("3", "۳");
number = number.replaceAll("4", "۴");
number = number.replaceAll("5", "۵");
number = number.replaceAll("6", "۶");
number = number.replaceAll("7", "۷");
number = number.replaceAll("8", "۸");
number = number.replaceAll("9", "۹");
number = number.replaceAll("0", "۰");
return number;
}
}
extension IntExtensions on int {
String persianNumber() {
String number = this.toString();
number = number.replaceAll("1", "۱");
number = number.replaceAll("2", "۲");
number = number.replaceAll("3", "۳");
number = number.replaceAll("4", "۴");
number = number.replaceAll("5", "۵");
number = number.replaceAll("6", "۶");
number = number.replaceAll("7", "۷");
number = number.replaceAll("8", "۸");
number = number.replaceAll("9", "۹");
number = number.replaceAll("0", "۰");
return number;
}
}

Banker's Rounding in Dart

Can anyone help with a Banker's rounding implementation in Dart please
So i round 3 d.p. to the nearest 2 d.p. number EXCEPT when the number is halfway between it goes to the nearest even number
eg
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
I have same requirement, so i build one.
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;
}
Here is a tested banker round to a whole numbers algorithm.
For Decimal (100% accurate):
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;
}
And for double:
double bankerRound(double value) {
var rounded = value.roundToDouble();
if(((rounded - value) * 100).round() == 50)
if(value.ceil() % 2 != 0)
rounded = value.floorToDouble();
return rounded;
}

How to remove trailing zeros using Dart

I would like the optimal solution for removing trailing zeros using Dart. If I have a double that is 12.0 it should output 12. If I have a double that is 12.5 it should output 12.5
I made regular expression pattern for that feature.
double num = 12.50; // 12.5
double num2 = 12.0; // 12
double num3 = 1000; // 1000
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
String s = num.toString().replaceAll(regex, '');
UPDATE
A better approach, just use this method:
String removeDecimalZeroFormat(double n) {
return n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 1);
}
OLD
This meets the requirements:
double x = 12.0;
double y = 12.5;
print(x.toString().replaceAll(RegExp(r'.0'), ''));
print(y.toString().replaceAll(RegExp(r'.0'), ''));
X Output: 12
Y Output: 12.5
Use NumberFormat:
String formatQuantity(double v) {
if (v == null) return '';
NumberFormat formatter = NumberFormat();
formatter.minimumFractionDigits = 0;
formatter.maximumFractionDigits = 2;
return formatter.format(v);
}
If what you want is to convert a double without decimals to an int but keep it as a double if it has decimals, I use this method:
num doubleWithoutDecimalToInt(double val) {
return val % 1 == 0 ? val.toInt() : val;
}
Lots of the answers don't work for numbers with many decimal points and are centered around monetary values.
To remove all trailing zeros regardless of length:
removeTrailingZeros(String n) {
return n.replaceAll(RegExp(r"([.]*0+)(?!.*\d)"), "");
}
Input: 12.00100003000
Output: 12.00100003
If you only want to remove trailing 0's that come after a decimal point, use this instead:
removeTrailingZerosAndNumberfy(String n) {
if(n.contains('.')){
return double.parse(
n.replaceAll(RegExp(r"([.]*0+)(?!.*\d)"), "") //remove all trailing 0's and extra decimals at end if any
);
}
else{
return double.parse(
n
);
}
}
I found another solution, to use num instead of double. In my case I'm parsing String to num:
void main() {
print(num.parse('50.05').toString()); //prints 50.05
print(num.parse('50.0').toString()); //prints 50
}
Here is what I've come up with:
extension DoubleExtensions on double {
String toStringWithoutTrailingZeros() {
if (this == null) return null;
return truncateToDouble() == this ? toInt().toString() : toString();
}
}
void main() {
group('DoubleExtensions', () {
test("toStringWithoutTrailingZeros's result matches the expected value for a given double",
() async {
// Arrange
final _initialAndExpectedValueMap = <double, String>{
0: '0',
35: '35',
-45: '-45',
100.0: '100',
0.19: '0.19',
18.8: '18.8',
0.20: '0.2',
123.32432400: '123.324324',
-23.400: '-23.4',
null: null
};
_initialAndExpectedValueMap.forEach((key, value) {
final initialValue = key;
final expectedValue = value;
// Act
final actualValue = initialValue.toStringWithoutTrailingZeros();
// Assert
expect(actualValue, expectedValue);
});
});
});
}
String removeTrailingZero(String string) {
if (!string.contains('.')) {
return string;
}
string = string.replaceAll(RegExp(r'0*$'), '');
if (string.endsWith('.')) {
string = string.substring(0, string.length - 1);
}
return string;
}
======= testcase below =======
000 -> 000
1230 -> 1230
123.00 -> 123
123.001 -> 123.001
123.00100 -> 123.001
abc000 -> abc000
abc000.0000 -> abc000
abc000.001 -> abc000.001
Here is a very simple way. Using if else I will check if the number equals its integer or it is a fraction and take action accordingly
num x = 24/2; // returns 12.0
num y = 25/2; // returns 12.5
if (x == x.truncate()) {
// it is true in this case so i will do something like
x = x.toInt();
}
To improve on What #John's answer: here is a shorter version.
String formatNumber(double n) {
return n.toStringAsFixed(0) //removes all trailing numbers after the decimal.
}
This function removes all trailing commas. It also makes it possible to specify a maximum number of digits after the comma.
extension ToString on double {
String toStringWithMaxPrecision({int? maxDigits}) {
if (round() == this) {
return round().toString();
} else {
if (maxDigits== null) {
return toString().replaceAll(RegExp(r'([.]*0)(?!.*\d)'), "");
} else {
return toStringAsFixed(maxDigits)
.replaceAll(RegExp(r'([.]*0)(?!.*\d)'), "");
}
}
}
}
//output without maxDigits:
// 1.0 -> 1
// 1.0000 -> 1
// 0.99990 -> 0.9999
// 0.103 -> 0.103
//
////output with maxDigits of 2:
// 1.0 -> 1
// 1.0000 -> 1
// 0.99990 -> 0.99
// 0.103 -> 0.1
user3044484's version with Dart extension:
extension StringRegEx on String {
String removeTrailingZero() {
if (!this.contains('.')) {
return this;
}
String trimmed = this.replaceAll(RegExp(r'0*$'), '');
if (!trimmed.endsWith('.')) {
return trimmed;
}
return trimmed.substring(0, this.length - 1);
}
}
// The syntax is same as toStringAsFixed but this one removes trailing zeros
// 1st toStringAsFixed() is executed to limit the digits to your liking
// 2nd toString() is executed to remove trailing zeros
extension Ex on double {
String toStringAsFixedNoZero(int n) =>
double.parse(this.toStringAsFixed(n)).toString();
}
// It works in all scenarios. Usage
void main() {
double length1 = 25.001;
double length2 = 25.5487000;
double length3 = 25.10000;
double length4 = 25.0000;
double length5 = 0.9;
print('\nlength1= ' + length1.toStringAsFixedNoZero(3));
print('\nlength2= ' + length2.toStringAsFixedNoZero(3));
print('\nlenght3= ' + length3.toStringAsFixedNoZero(3));
print('\nlenght4= ' + length4.toStringAsFixedNoZero(3));
print('\nlenght5= ' + length5.toStringAsFixedNoZero(0));
}
// output:
// length1= 25.001
// length2= 25.549
// lenght3= 25.1
// lenght4= 25
// lenght5= 1
you can do a simple extension on the double class
and add a function which in my case i called it neglectFractionZero()
in this extension function on double(which returns a string) i
split the converted number to string and i check if the split part of the string is "0" , if so i return the first part only of the split and i neglect this zero
you can modify it according to your needs
extension DoubleExtension on double {
String neglectFractionZero() {
return toString().split(".").last == "0"? toString().split(".").first:toString();
}
}
I've came up with improved version of #John.
static String getDisplayPrice(double price) {
price = price.abs();
final str = price.toStringAsFixed(price.truncateToDouble() == price ? 0 : 2);
if (str == '0') return '0';
if (str.endsWith('.0')) return str.substring(0, str.length - 2);
if (str.endsWith('0')) return str.substring(0, str.length -1);
return str;
}
// 10 -> 10
// 10.0 -> 10
// 10.50 -> 10.5
// 10.05 -> 10.05
// 10.000000000005 -> 10
void main() {
double x1 = 12.0;
double x2 = 12.5;
String s1 = x1.toString().trim();
String s2 = x2.toString().trim();
print('s1 is $s1 and s2 is $s2');
}
try trim method https://api.dartlang.org/stable/2.2.0/dart-core/String/trim.html

Random number from an array without repeating the same number twice in a row?

I am making a game using Swift and SpriteKit where i move an object to random locations based on an array.
The array that is made up of CGPoints:
let easyArray = [CGPointMake(0,0), CGPointMake(126.6,0), CGPointMake(253.4,0), CGPointMake(0,197.5), CGPointMake(126.7,197.5), CGPointMake(253.4,197.5), CGPointMake(0,395), CGPointMake(126.7,395), CGPointMake(253.4,395)]
I use this function to generate a random number:
func randomNumber(maximum: UInt32) -> Int {
var randomNumber = arc4random_uniform(maximum)
while previousNumber == randomNumber {
randomNumber = arc4random_uniform(maximum)
}
previousNumber = randomNumber
return Int(randomNumber)
}
I used this to move the object based on the random number generated:
let greenEasy = randomNumberNew(9)
let moveSelector = SKAction.moveTo(easyArray[greenEasy], duration: 0)
selector.runAction(moveSelector)
I have done some reading online and found that the "While" condition should make it so that the same random number isn't generate twice in a row. But it still happens.
Can anyone please help me on how to make it so i don't get the same number twice in a row?
The code below doesn't random the same number.
var currentNo: UInt32 = 0
func randomNumber(maximum: UInt32) -> Int {
var randomNumber: UInt32
do {
randomNumber = (arc4random_uniform(maximum))
}while currentNo == randomNumber
currentNo = randomNumber
return Int(randomNumber)
}
I think Larme's suggestion is pretty clever, actually.
easyArray.append(easyArray.removeAtIndex(Int(arc4random_uniform(UInt32(easyArray.count)-1))))
selector.runAction(SKAction.moveTo(easyArray.last!, duration: 0))
I would recommend to not use while() loops with randomizers.
Theoretically it can cause infinite loops in worst case scenario, in more positive scenario it will just take few loops before you get desired results.
Instead I would advice to make an NSArray of all values, remove from this NSArray last randomized element and randomize any of other existing elements from such an array - that is guarantee result after only one randomize iteration.
It can be easily achieved by making NSArray category in Objective-C:
- (id) randomARC4Element
{
if(self.count > 0)
{
return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
}
return nil;
}
- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}
- (float)randomFloat
{
return (float) arc4random() / UINT_MAX;
}
If you can use linq then you can select a random value that doesn't match the last value. Then for any left over values you can loop through and find valid places to insert them.
It's not the most efficient but it works.
public static List<int> Randomize(List<int> reps, int lastId) {
var rand = new Random();
var newReps = new List<int>();
var tempReps = new List<int>();
tempReps.AddRange(reps);
while (tempReps.Any(x => x != lastId)) {
var validReps = tempReps.FindAll(x => x != lastId);
var i = rand.Next(0, validReps.Count - 1);
newReps.Add(validReps[i]);
lastId = validReps[i];
tempReps.Remove(validReps[i]);
}
while (tempReps.Any()) {
var tempRep = tempReps.First();
bool placed = false;
for (int i = 0; i < newReps.Count; i++) {
if (newReps[i] == tempRep) {
continue;
}
else if ((i < newReps.Count - 1) && (newReps[i + 1] == tempRep)) {
continue;
}
else {
newReps.Insert(i + 1, tempRep);
placed = true;
break;
}
}
if (placed) {
tempReps.Remove(tempRep);
}
else {
throw new Exception("Unable to randomize reps");
}
}
return newReps;
}

Comma format a number

I need to format numbers with commas as thousand seperators, for example:
1234 = 1,234
1234.50 = 1,234.50
12345.60 = 12,345.60
123456.70 = 123,456.70
1234567.80 = 1,234,567.80
etc etc
This needs to work for numbers with decimal values or without
i.e. both 1234567.80 and 1234567
This is for Actionscript 2 in a Coldfusion / Flash application, so normal actionscript is being used. I have seen a couple of solutions on the net but none quite do the trick.
So far I have the function below, but it is not formatting correctly when decimals are provided.For example: 21898.5 becomes 2,188,8.5.
Please could you help me find the bug or offer an alternative solution that fulfils the requriements.
Thanks
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(theNumber.indexOf('.') > 0)
{
myArray = theNumber.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numString.length > 3)
{
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
if (numString.length > 0)
{
result = numString + result;
}
if(theNumber.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
You could try this:
_global.NumberFormat = function(numString)
{
numString = String(numString);
var index:Number = numString.indexOf('.');
var decimal:String;
if(index > 0) {
var splitByDecimal:Array = numString.split(".");
//return NumberFormat(splitByDecimal[0])+"."+splitByDecimal[1];
numString = splitByDecimal[0];
decimal = splitByDecimal[1];
} else if(index === 0) {
return "0"+numString;
}
var result:String = '';
while (numString.length > 3 ) {
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
result = numString + result;
if(decimal) result = result + "." + decimal;
return result;
}
It splits the number by the decimal if present(compensating for an illegal '.01234' if required), and uses recursion so call itself on the split element.
For your example numbers this traces:
1,234
1,234.50
12,345.60
123,456.70
1,234,567.80
Just for fun
This is why your original code didn't work:
After creating a string representation of the number (var numString:String = theNumber.toString();) you then carried on using the actual number rather than the string version.
After assigning a value to number part you then continued to perform operations on numString rather than numberPart.
A corrected version looks like this:
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(numString.indexOf('.') > 0)
{
myArray = numString.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numberPart.length > 3)
{
var chunk:String = numberPart.substr(-3);
numberPart = numberPart.substr(0, numberPart.length - 3);
result = ',' + chunk + result;
}
if (numberPart.length > 0)
{
result = numberPart + result;
}
if(numString.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
public static function formatNumberString(value:Number,separator:String):String {
var result:String = "";
var digitsCount:Number = value.toString().length;
separator = separator || ",";
for (var i:Number = 0; i < digitsCount; i++) {
if ((digitsCount - i) % 3 == 0 && i != 0) {
result += separator;
}
result += value.toString().charAt(i);
}
return result;
}
Try this out, works fine for me:
var largeNumber:String=new String(1000000.999777);
var fAr:Array=largeNumber.split(".");
var reg:RegExp=/\d{1,3}(?=(\d{3})+(?!\d))/;
while(reg.test(fAr[0]))
fAr[0]=fAr[0].replace(reg,"$&,");
var res:String=fAr.join(".");
trace(res);
Trace: 1,000,000.999777

Resources