Banker's Rounding in Dart - 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;
}

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;
}
}

BMI Calculation Xcode [duplicate]

Can anyone tell me how to round a double value to x number of decimal places in Swift?
I have:
var totalWorkTimeInHours = (totalWorkTime/60/60)
With totalWorkTime being an NSTimeInterval (double) in second.
totalWorkTimeInHours will give me the hours, but it gives me the amount of time in such a long precise number e.g. 1.543240952039......
How do I round this down to, say, 1.543 when I print totalWorkTimeInHours?
You can use Swift's round function to accomplish this.
To round a Double with 3 digits precision, first multiply it by 1000, round it and divide the rounded result by 1000:
let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236
Unlike any kind of printf(...) or String(format: ...) solutions, the result of this operation is still of type Double.
EDIT:
Regarding the comments that it sometimes does not work, please read this: What Every Programmer Should Know About Floating-Point Arithmetic
Extension for Swift 2
A more general solution is the following extension, which works with Swift 2 & iOS 9:
extension Double {
/// Rounds the double to decimal places value
func roundToPlaces(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(self * divisor) / divisor
}
}
Extension for Swift 3
In Swift 3 round is replaced by rounded:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
Example which returns Double rounded to 4 decimal places:
let x = Double(0.123456789).roundToPlaces(4) // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4) // Swift 3 version
How do I round this down to, say, 1.543 when I print totalWorkTimeInHours?
To round totalWorkTimeInHours to 3 digits for printing, use the String constructor which takes a format string:
print(String(format: "%.3f", totalWorkTimeInHours))
With Swift 5, according to your needs, you can choose one of the 9 following styles in order to have a rounded result from a Double.
#1. Using FloatingPoint rounded() method
In the simplest case, you may use the Double rounded() method.
let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#2. Using FloatingPoint rounded(_:) method
let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#3. Using Darwin round function
Foundation offers a round function via Darwin.
import Foundation
let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#4. Using a Double extension custom method built with Darwin round and pow functions
If you want to repeat the previous operation many times, refactoring your code can be a good idea.
import Foundation
extension Double {
func roundToDecimal(_ fractionDigits: Int) -> Double {
let multiplier = pow(10, Double(fractionDigits))
return Darwin.round(self * multiplier) / multiplier
}
}
let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#5. Using NSDecimalNumber rounding(accordingToBehavior:) method
If needed, NSDecimalNumber offers a verbose but powerful solution for rounding decimal numbers.
import Foundation
let scale: Int16 = 3
let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)
let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#6. Using NSDecimalRound(_:_:_:_:) function
import Foundation
let scale = 3
var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)
var roundedValue1 = Decimal()
var roundedValue2 = Decimal()
NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#7. Using NSString init(format:arguments:) initializer
If you want to return a NSString from your rounding operation, using NSString initializer is a simple but efficient solution.
import Foundation
let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685
#8. Using String init(format:_:) initializer
Swift’s String type is bridged with Foundation’s NSString class. Therefore, you can use the following code in order to return a String from your rounding operation:
import Foundation
let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685
#9. Using NumberFormatter
If you expect to get a String? from your rounding operation, NumberFormatter offers a highly customizable solution.
import Foundation
let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3
let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")
In Swift 5.5 and Xcode 13.2:
let pi: Double = 3.14159265358979
String(format:"%.2f", pi)
Example:
PS.: It still the same since Swift 2.0 and Xcode 7.2
This is a fully worked code
Swift 3.0/4.0/5.0 , Xcode 9.0 GM/9.2 and above
let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)
output - 123
let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)
output - 123.3
let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)
output - 123.33
let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)
output - 123.326
Building on Yogi's answer, here's a Swift function that does the job:
func roundToPlaces(value:Double, places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(value * divisor) / divisor
}
In Swift 3.0 and Xcode 8.0:
extension Double {
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
Use this extension like so:
let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
Swift 4, Xcode 10
yourLabel.text = String(format:"%.2f", yourDecimalValue)
The code for specific digits after decimals is:
var a = 1.543240952039
var roundedString = String(format: "%.3f", a)
Here the %.3f tells the swift to make this number rounded to 3 decimal places.and if you want double number, you may use this code:
// String to Double
var roundedString = Double(String(format: "%.3f", b))
Use the built in Foundation Darwin library
SWIFT 3
extension Double {
func round(to places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
Usage:
let number:Double = 12.987654321
print(number.round(to: 3))
Outputs: 12.988
If you want to round Double values, you might want to use Swift Decimal so you don't introduce any errors that can crop up when trying to math with these rounded values. If you use Decimal, it can accurately represent decimal values of that rounded floating point value.
So you can do:
extension Double {
/// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
///
/// - Parameters:
/// - scale: How many decimal places to round to. Defaults to `0`.
/// - mode: The preferred rounding mode. Defaults to `.plain`.
/// - Returns: The rounded `Decimal` value.
func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
var decimalValue = Decimal(self)
var result = Decimal()
NSDecimalRound(&result, &decimalValue, scale, mode)
return result
}
}
Then, you can get the rounded Decimal value like so:
let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30
And if you want to display it with a specified number of decimal places (as well as localize the string for the user's current locale), you can use a NumberFormatter:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
A handy way can be the use of extension of type Double
extension Double {
var roundTo2f: Double {return Double(round(100 *self)/100) }
var roundTo3f: Double {return Double(round(1000*self)/1000) }
}
Usage:
let regularPie: Double = 3.14159
var smallerPie: Double = regularPie.roundTo3f // results 3.142
var smallestPie: Double = regularPie.roundTo2f // results 3.14
This is a sort of a long workaround, which may come in handy if your needs are a little more complex. You can use a number formatter in Swift.
let numberFormatter: NSNumberFormatter = {
let nf = NSNumberFormatter()
nf.numberStyle = .DecimalStyle
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
Suppose your variable you want to print is
var printVar = 3.567
This will make sure it is returned in the desired format:
numberFormatter.StringFromNumber(printVar)
The result here will thus be "3.6" (rounded). While this is not the most economic solution, I give it because the OP mentioned printing (in which case a String is not undesirable), and because this class allows for multiple parameters to be set.
Either:
Using String(format:):
Typecast Double to String with %.3f format specifier and then back to Double
Double(String(format: "%.3f", 10.123546789))!
Or extend Double to handle N-Decimal places:
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
return Double(String(format: "%.\(n)f", self))!
}
}
By calculation
multiply with 10^3, round it and then divide by 10^3...
(1000 * 10.123546789).rounded()/1000
Or extend Double to handle N-Decimal places:
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
let multiplier = pow(10, Double(n))
return (multiplier * self).rounded()/multiplier
}
}
I would use
print(String(format: "%.3f", totalWorkTimeInHours))
and change .3f to any number of decimal numbers you need
This is more flexible algorithm of rounding to N significant digits
Swift 3 solution
extension Double {
// Rounds the double to 'places' significant digits
func roundTo(places:Int) -> Double {
guard self != 0.0 else {
return 0
}
let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
return (self * divisor).rounded() / divisor
}
}
// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200
The best way to format a double property is to use the Apple predefined methods.
mutating func round(_ rule: FloatingPointRoundingRule)
FloatingPointRoundingRule is a enum which has following possibilities
Enumeration Cases:
case awayFromZero
Round to the closest allowed value whose magnitude is greater than or equal to that of the source.
case down
Round to the closest allowed value that is less than or equal to the source.
case toNearestOrAwayFromZero
Round to the closest allowed value; if two values are equally close, the one with greater magnitude is chosen.
case toNearestOrEven
Round to the closest allowed value; if two values are equally close, the even one is chosen.
case towardZero
Round to the closest allowed value whose magnitude is less than or equal to that of the source.
case up
Round to the closest allowed value that is greater than or equal to the source.
var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
round a double value to x number of decimal
NO. of digits after decimal
var x = 1.5657676754
var y = (x*10000).rounded()/10000
print(y) // 1.5658
var x = 1.5657676754
var y = (x*100).rounded()/100
print(y) // 1.57
var x = 1.5657676754
var y = (x*10).rounded()/10
print(y) // 1.6
For ease to use, I created an extension:
extension Double {
var threeDigits: Double {
return (self * 1000).rounded(.toNearestOrEven) / 1000
}
var twoDigits: Double {
return (self * 100).rounded(.toNearestOrEven) / 100
}
var oneDigit: Double {
return (self * 10).rounded(.toNearestOrEven) / 10
}
}
var myDouble = 0.12345
print(myDouble.threeDigits)
print(myDouble.twoDigits)
print(myDouble.oneDigit)
The print results are:
0.123
0.12
0.1
Thanks for the inspiration of other answers!
Not Swift but I'm sure you get the idea.
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
Swift 5
using String method
var yourDouble = 3.12345
//to round this to 2 decimal spaces i could turn it into string
let roundingString = String(format: "%.2f", myDouble)
let roundedDouble = Double(roundingString) //and than back to double
// result is 3.12
but it's more accepted to use extension
extension Double {
func round(to decimalPlaces: Int) -> Double {
let precisionNumber = pow(10,Double(decimalPlaces))
var n = self // self is a current value of the Double that you will round
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
and then you can use:
yourDouble.round(to:2)
This seems to work in Swift 5.
Quite surprised there isn't a standard function for this already.
//Truncation of Double to n-decimal places with rounding
extension Double {
func truncate(to places: Int) -> Double {
return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
}
}
To avoid Float imperfections use Decimal
extension Float {
func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
var result: Decimal = 0
var decimalSelf = NSNumber(value: self).decimalValue
NSDecimalRound(&result, &decimalSelf, scale, rule)
return (result as NSNumber).floatValue
}
}
ex.
1075.58 rounds to 1075.57 when using Float with scale: 2 and .down
1075.58 rounds to 1075.58 when using Decimal with scale: 2 and .down
var n = 123.111222333
n = Double(Int(n * 10.0)) / 10.0
Result: n = 123.1
Change 10.0 (1 decimal place) to any of 100.0 (2 decimal place), 1000.0 (3 decimal place) and so on, for the number of digits you want after decimal..
The solution worked for me. XCode 13.3.1 & Swift 5
extension Double {
func rounded(decimalPoint: Int) -> Double {
let power = pow(10, Double(decimalPoint))
return (self * power).rounded() / power
}
}
Test:
print(-87.7183123123.rounded(decimalPoint: 3))
print(-87.7188123123.rounded(decimalPoint: 3))
print(-87.7128123123.rounded(decimalPoint: 3))
Result:
-87.718
-87.719
-87.713
I found this wondering if it is possible to correct a user's input. That is if they enter three decimals instead of two for a dollar amount. Say 1.111 instead of 1.11 can you fix it by rounding? The answer for many reasons is no! With money anything over i.e. 0.001 would eventually cause problems in a real checkbook.
Here is a function to check the users input for too many values after the period. But which will allow 1., 1.1 and 1.11.
It is assumed that the value has already been checked for successful conversion from a String to a Double.
//func need to be where transactionAmount.text is in scope
func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{
var theTransactionCharacterMinusThree: Character = "A"
var theTransactionCharacterMinusTwo: Character = "A"
var theTransactionCharacterMinusOne: Character = "A"
var result = false
var periodCharacter:Character = "."
var myCopyString = transactionAmount.text!
if myCopyString.containsString(".") {
if( myCopyString.characters.count >= 3){
theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)]
}
if( myCopyString.characters.count >= 2){
theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)]
}
if( myCopyString.characters.count > 1){
theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)]
}
if theTransactionCharacterMinusThree == periodCharacter {
result = true
}
if theTransactionCharacterMinusTwo == periodCharacter {
result = true
}
if theTransactionCharacterMinusOne == periodCharacter {
result = true
}
}else {
//if there is no period and it is a valid double it is good
result = true
}
return result
}
You can add this extension :
extension Double {
var clean: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
}
}
and call it like this :
let ex: Double = 10.123546789
print(ex.clean) // 10.12
Here's one for SwiftUI if you need a Text element with the number value.
struct RoundedDigitText : View {
let digits : Int
let number : Double
var body : some View {
Text(String(format: "%.\(digits)f", number))
}
}
//find the distance between two points
let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 )
let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599)
let distanceInMeters = coordinateSource.distance(from: coordinateDestination)
let valueInKms = distanceInMeters/1000
let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000)
self.lblTotalDistance.text = "Distance is : \(preciseValueUptoThreeDigit) kms"

how to round up a double value in flutter

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);

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

Integers Larger than Int64

I'm attempting to get a user input number and find the sum of all the digits. I'm having issues with larger numbers, however, as they won't register under an Int64. Any idea as to what structures I could use to store the value? (I tried UInt64 and that didn't work very well with negatives, however, I'd prefer something larger than UInt64, anyways. I'm having a hard time implementing a UInt128 from Is there a number type with bigger capacity than u_long/UInt64 in Swift?)
import Foundation
func getInteger() -> Int64 {
var value:Int64 = 0
while true {
//we aren't doing anything with input, so we make it a constant
let input = readLine()
//ensure its not nil
if let unwrappedInput = input {
if let unwrappedInt = Int64(unwrappedInput) {
value = unwrappedInt
break
}
}
else { print("You entered a nil. Try again:") }
}
return value
}
print("Please enter an integer")
// Gets user input
var input = getInteger()
var arr = [Int] ()
var sum = 0
var negative = false
// If input is less than 0, makes it positive
if input < 0 {
input = (input * -1)
negative = true
}
if (input < 10) && (input >= 1) && (negative == true) {
var remain = (-1)*(input%10)
arr.append(Int(remain))
input = (input/10)
}
else {
var remain = (input%10)
arr.append(Int(remain))
input = (input/10)
}
}
// Adds numbers in array to find sum of digits
var i:Int = 0
var size:Int = (arr.count - 1)
while i<=size {
sum = sum + arr[i]
i = (i+1)
}
// Prints sum
print("\(sum)")
You can use a string to perform the operation you describe. Loop through each character and convert it to an integer and add to the sum. Be careful to handle errors.

Resources