In Dart is there a quick way to convert int to double? - dart

Very simple issue. I have the useless class:
class Useless{
double field;
Useless(this.field);
}
I then commit the mortal sin and call new Useless(0);
In checked mode (which is how I run my tests) that blows up, because 'int' is not a subtype of type 'double'.
Now, it works if I use new Useless(0.0) , but honestly I spend a lot of time correcting my tests putting .0s everywhere and I feel pretty dumb doing that.
As a temporary measure I rewrote the constructor as:
class Useless{
double field;
Useless(num input){
field = input.toDouble();
}
}
But that's ugly and I am afraid slow if called often. Is there a better way to do this?

Simply toDouble()
Example:
int intVar = 5;
double doubleVar = intVar.toDouble();
Thanks to #jamesdlin who actually gave this answer in a comment to my previous answer...

In Dart 2.1, integer literals may be directly used where double is expected. (See https://github.com/dart-lang/sdk/issues/34355.)
Note that this is syntactic sugar and applies only to literals. int variables still won't be automatically promoted to double, so code like:
double reciprocal(double d) => 1 / d;
int x = 42;
reciprocal(x);
would fail, and you'd need to do:
reciprocal(x.toDouble());

You can also use:
int x = 15;
double y = x + .0;

use toDouble() method.
For e.g.:
int a = 10
print(a.toDouble)
//or store value in a variable and then use
double convertedValue = a.toDouble()

From this attempt:
class Useless{
double field;
Useless(num input){
field = input.toDouble();
}
}
You can use the parse method of the double class which takes in a string.
class Useless{
double field;
Useless(num input){
field = double.parse(input.toString()); //modified line
}
}
A more compact way of writing the above class using constructor's initialisers is:
class Useless{
double _field;
Useless(double field):_field=double.parse(field.toString());
}

Since all divisions in flutter result to a double, the easiest thing I did to achieve this was just to divide the integer value with 1:
i.e.
int x = 15;
double y = x /1;

There's no better way to do this than the options you included :(
I get bitten by this lots too, for some reason I don't get any warnings in the editor and it just fails at runtime; mighty annoying :(

I'm using a combination:
static double checkDouble(dynamic value) {
if (value is String) {
return double.parse(value);
} else if (value is int) {
return 0.0 + value;
} else {
return value;
}
}

This is how you can cast from int to double
int a = 2;
double b = a*1.0;

Related

casting MapValue to double and multiply to double in dart

Iam new to dart I want a Make table of food program which take an input from user for each food and how much they want but i have an problem with multiply listOfFood[name] with count which both of them double is there any way to solve this ?
double name , count ;
Map<String , dynamic> listOfFood = {
'bacon' :'4.2',
'salad' :'3.5',
'cheaken' :'5.6',
'Goatmeat' :'6.9',
'fish' : '6.5',
};
Map<int , dynamic> food = {
1 : listOfFood ['bacon']
,2 : listOfFood ['salad']
,3 : listOfFood ['cheaken']
,4 : listOfFood ['Goatmeat']
,5 : listOfFood ['fish']
};
stdout.write('please Choose your product \n ${listOfFood}');
name = double.parse(stdin.readLineSync()!);
count = double.parse(stdin.readLineSync()!);
double result = (food[name]) * count;
print(result);
}
You cannot coerce a String that looks like a number to a double in Dart.
Dart has strong typing even when you declare a variable dynamic.
In your case, you're taking the value from listOfFood (not a List, use a better name like priceByFoodName), which is always a String (despite the Map having dynamic values) and multiplying that with a double which can't work.
You should ask yourself why are the prices Strings?
If you want to use them as numbers, just make them numbers.
Also, you don't need dynamic at all. Use types! If you had done that the compiler would've told you right away what the problem was before you even ran the code. That's why types exist.
To solve the problem quickly... this line:
double result = (food[name]) * count;
Should be changed to:
double result = double.parse(food[name]!) * count;
But you should probably change your code quite a bit to handle errors, use appropriate types, stop ignoring nulls etc.

How to return two specific types from a generic method?

T getValue<T>(int i) {
if (T == String) return '$i'; // Error
return i; // Error
}
void main() {
var s = getValue<String>(1);
var i = getValue<int>(1);
}
I want getValue to return string if T is String and int otherwise. How to do that?
You can't restrict the type parameter to just int or String, so it will have to accept more than that (at least their least common supertype, Object, so basically any type).
It's not a particularly helpful way to code. It's possible, but not recommended:
T getValue<T>(int i) {
if (i is T) return i;
return "$i" as T;
}
This will return the int if T allows it (so T being any of int, or a super type of int, which is num, Object, dynamic or void, or any number of Comparable<X> wrappings around any any of those supertypes), and otherwise try to return a string. That will fail with a type error unless T is String (since we've already ruled out all supertypes of String).
You can still call it as getValue<bool>(42) and watch it fail, so the type argument doesn't help with correctness.
It's not particularly effective. I'd rather do:
dynamic getValue(int i, {bool toString = false}) {
if (toString) return "$i";
return i;
}
and call it as:
String x = getValue(42, toString: true); // Add `as String` if you disable downcasts.
int y = getValue(42); // And `as int` here.
The type parameter is really just making things harder. You are going to cast or type-check the result anyway, so might as well do it at the call point, rather than introduce type variables that aren't actually preventing misuse anyway.
(I'd probably just do two different functions, but I assume that there is a reason for wanting one function).
As I mentioned in the comments, I don't see any way that you could use your generic as the return type of your getValue function. Even assuming the return under the if statement worked, there is nothing that can be done about trying to return int i when List is passed as the type. You'll be trying to return an int as a List.
If you change it to dynamic, your code will work fine as it's just using the generic as another parameter.
dynamic getValue<T>(int i) {
if (T == String) return '$i';
return i;
}
void main() {
var s = getValue<String>(1);
var i = getValue<int>(1);
}

Function in C returns initial value of a variable

I just started programming and I have struggle understanding functions with return value. I tried for example to make function that returns the absolute value of a real number:
include
double absol(double x) {
if (x>0) {
return (x);
}
else {
return (-x);
}
}
main() {
double x;
scanf("%fl",&x);
printf("%f",absol(x));
}
It give zero back and if I change the initial value of x, it gives this value back. Why doesn't it take the value that I input with scanf?
Thank you.
scanf("%fl",&x); will not correctly read in a double. You need scanf("%lf",&x); instead.

Why can't I convert a Number into a Double?

weight is a field (Number in Firestore), set as 100.
int weight = json['weight'];
double weight = json['weight'];
int weight works fine, returns 100 as expected, but double weight crashes (Object.noSuchMethod exception) rather than returning 100.0, which is what I expected.
However, the following works:
num weight = json['weight'];
num.toDouble();
When parsing 100 from Firestore (which actually does not support a "number type", but converts it), it will by standard be parsed to an int.
Dart does not automatically "smartly" cast those types. In fact, you cannot cast an int to a double, which is the problem you are facing. If it were possible, your code would just work fine.
Parsing
Instead, you can parse it yourself:
double weight = json['weight'].toDouble();
Casting
What also works, is parsing the JSON to a num and then assigning it to a double, which will cast num to double.
double weight = json['weight'] as num;
This seems a bit odd at first and in fact the Dart Analysis tool (which is e.g. built in into the Dart plugin for VS Code and IntelliJ) will mark it as an "unnecessary cast", which it is not.
double a = 100; // this will not compile
double b = 100 as num; // this will compile, but is still marked as an "unnecessary cast"
double b = 100 as num compiles because num is the super class of double and Dart casts super to sub types even without explicit casts.
An explicit cast would be the follwing:
double a = 100 as double; // does not compile because int is not the super class of double
double b = (100 as num) as double; // compiles, you can also omit the double cast
Here is a nice read about "Types and casting in Dart".
Explanation
What happened to you is the following:
double weight;
weight = 100; // cannot compile because 100 is considered an int
// is the same as
weight = 100 as double; // which cannot work as I explained above
// Dart adds those casts automatically
You can do it in one line:
double weight = (json['weight'] as num).toDouble();
You can Parse the data Like given below:
Here document is a Map<String,dynamic>
double opening = double.tryParse(document['opening'].toString());
In Dart, int and double are separate types, both subtypes of num.
There is no automatic conversion between number types. If you write:
num n = 100;
double d = n;
you will get a run-time error. Dart's static type system allows unsafe down-casts, so the unsafe assignment of n to d (unsafe because not all num values are double values) is treated implicitly as:
num n = 100;
double d = n as double;
The as double checks that the value is actually a double (or null), and throws if it isn't. If that check succeeds, then it can safely assign the value to d since it is known to match the variable's type.
That's what's happening here. The actual value of json['weight'] (likely with static type Object or dynamic) is the int object with value 100. Assigning that to int works. Assigning it to num works. Assigning it to double throws.
The Dart JSON parser parses numbers as integers if they have no decimal or exponent parts (0.0 is a double, 0e0 is a double, 0 is an integer). That's very convenient in most cases, but occasionally annoying in cases like yours where you want a double, but the code creating the JSON didn't write it as a double.
In cases like that, you just have to write .toDouble() on the values when you extract them. That's a no-op on actual doubles.
As a side note, Dart compiled to JavaScript represents all numbers as the JavaScript Number type, which means that all numbers are doubles. In JS compiled code, all integers can be assigned to double without conversion. That will not work when the code is run on a non-JS implementation, like Flutter, Dart VM/server or ahead-of-time compilation for iOS, so don't depend on it, or your code will not be portable.
Simply convert int to double like this
int a = 10;
double b = a + 0.0;

How to get the length of an array?

How to get the length of a string array like
str 30 name[];//dynamic array
I used the following for getting the length,but it showing the error as "the variable is not of the type CLASS."
int len=name.get_length();
It sounds like you might be happier using the Array collection class.
http://msdn.microsoft.com/en-us/library/array.aspx
static void TestArray(Args _args)
{
Array strArray = new Array(Types::String);
;
strArray.value(1, 'abc');
strArray.value(2, 'def');
info(strfmt("%1", strArray.lastIndex()));
}
You need the dimOf function. Take a look to the reference:
http://msdn.microsoft.com/en-us/library/aa597117.aspx
Sorry, there is no build-in function to return the string array size. Since you are in full control what you put in the array, there need not be any!
The built-in function dimof returns the allocated size of the array, which is only of practical value for a fixed size array like str 30 name[20], where dimof(name) returns 20.
A clean way to remain in control, is to use a setter function:
static void TestArray(Args _args)
{
str 30 name[];
int n = 0;
int i;
void nameSet(int _i, str 30 _name)
{
n = max(n,_i);
name[_i] = _name;
}
;
nameSet(2,'abc');
nameSet(4,'def');
for (i = 1; i <= n; i++)
info(name[i]);
}
There is no upper bound index limit, so accessing name[7] is perfectly valid and in this case returns a blank value. This may be used to your advantage, if you always use all holes and never stores a blank:
static void TestArray(Args _args)
{
str 30 name[];
int i;
name[1] = 'abc';
name[2] = 'def';
for (i = 1; name[i]; i++)
info(name[i]);
}
Beware that accessing a higher index (in this case higher than 2) may in fact increase the allocated size of the array.

Resources