I have the following C# function:
public (double? Average, int? Count) AverageQuotes(Candle.Intervals Interval, DateTime From, DateTime To)
and I get the data in F#:
let struct (average, count) = db.AverageQuotes(previous, time, time + timespan)
The problem is that Average leaves the C# as a double? and arrives in the F# as Nullable so there is a double -> float conversion happening somewhere.
How can I keep the result as a double?
In F#, float and double are aliases for System.Double. The aliases for 32-bit doubles are float32 and single. See basic types or section 18.1 of the specification (PDF)
Related
I have a float (rate) that can be set by the user for this app. I would like to keep this variable persistent, so I would like to use the #AppStorage property wrapper. The problem I'm having is that #AppStorage("rate) var rate: Float = 0.5 gives No exact matches in call to initializer. After some brief googling, I learned that you cannot store floats with app storage. Is there a way to work around this?
Looking at the definition of AppStorage you can find the following allowed types:
Bool
Int
Double
String
URL
Data
enum with Int raw value
enum with String raw value
Bool?
Int?
Double?
String?
URL?
Data?
optional enum with Int raw value
optional enum with String raw value
So you should probably use Double, rather than Float (you shouldn't really use Float anyway, since it's 32-bit rather than 64-bit).
This question already has an answer here:
Why 2.0 (the number 2.0) is double and int at the same time?
(1 answer)
Closed 2 years ago.
The following code outputs the following results:
double firstValue = 1.2;
print('type of firstValue: ${firstValue.runtimeType}'); // double
double secondValue = 1;
print('type of secondValue: ${secondValue.runtimeType}'); // int
print('type of secondValue parsed: ${secondValue.toDouble().runtimeType}'); // int
Why a declared double value is understood like an int value? Even when I do an explicit cast, the the 1 value is still an int.
Why does this happen?
I presume that you see those results with dart2js (including DartPad).
JavaScript does not have separate int and double types; it uses IEEE-754 double-precision floating-point values everywhere. When Dart is transpiled to JavaScript, Dart's int and double types thus are both backed by the same type, and conversion back to Dart types requires heuristics since the type information was lost.
If you try your code with the Dart VM, you should see the results that you expect.
How can I elevate a double type of data to a power, in the language of Dart
for instance
1.08 raised to 2.05
because with the pow() function provided by dart:math I can only assign integer values .
I'm new. Sorry if the question is silly.
It works with double. The pow function parameters are of type num which can be int or double
An example here
void main(){
print(pow(1.08,2.05));
}
Consider updating dart.
I have trouble with integer division in Dart as it gives me error: 'Breaking on exception: type 'double' is not a subtype of type 'int' of 'c'.'
Here's the following code:
int a = 500;
int b = 250;
int c;
c = a / b; // <-- Gives warning in Dart Editor, and throws an error in runtime.
As you see, I was expecting that the result should be 2, or say, even if division of 'a' or 'b' would have a result of a float/double value, it should be converted directly to integer value, instead of throwing error like that.
I have a workaround by using .round()/.ceil()/.floor(), but this won't suffice as in my program, this little operation is critical as it is called thousands of times in one game update (or you can say in requestAnimationFrame).
I have not found any other solution to this yet, any idea? Thanks.
Dart version: 1.0.0_r30798
That is because Dart uses double to represent all numbers in dart2js. You can get interesting results, if you play with that:
Code:
int a = 1;
a is int;
a is double;
Result:
true
true
Actually, it is recommended to use type num when it comes to numbers, unless you have strong reasons to make it int (in for loop, for example). If you want to keep using int, use truncating division like this:
int a = 500;
int b = 250;
int c;
c = a ~/ b;
Otherwise, I would recommend to utilize num type.
Integer division is
c = a ~/ b;
you could also use
c = (a / b).floor();
c = (a / b).ceil();
if you want to define how fractions should be handled.
Short Answer
Use c = a ~/ b.
Long Answer
According to the docs, int are numbers without a decimal point, while double are numbers with a decimal point.
Both double and int are subtypes of num.
When two integers are divided using the / operator, the result is evaluated into a double. And the c variable was initialized as an integer. There are at least two things you can do:
Use c = a ~/ b.
The ~/ operator returns an int.
Use var c;. This creates a dynamic variable that can be assigned to any type, including a double and int and String etc.
Truncating division operator
You can use the truncating division operator ~/ to get an integer result from a division operation:
4 ~/ 2; // 2 (int)
Division operator
The regular division operator / will always return a double value at runtime (see the docs):
for (var i = 4; i == 4; i = 3) {
i / 2; // 2 (double)
}
Runtime versus compile time
You might have noticed that I wrote a loop for the second example (for the regular division operator) instead of 4 / 2.
The reason for this is the following:
When an expression can be evaluated at compile time, it will be simplified at that stage and also be typed accordingly. The compiler would simply convert 4 / 2 to 2 at compile time, which is then obviously an int. The loop prevents the compiler from evaluating the expression.
As long as your division happens at runtime (i.e. with variables that cannot be predicted at compile time), the return types of the / (double) and ~/ (int) operators will be the types you will see for your expressions at runtime.
See this fun example for further reference.
Conclusion
Generally speaking, the regular division operator / always returns a double value and truncate divide can be used to get an int result instead.
Compiler optimization might, however, cause some funky results :)
How can I convert an Int64 to an Int32 type in F# without using the Microsoft.FSharp.Compatibility.Int32.of_int64?
I'm doing this because interactive doesn't seem to work when I try:
open Microsoft.FSharp.Compatibility
With FSharp.PowerPack added as a reference it says:
error FS0039: The namespace 'Compatibility' is not defined.
Edit: Does anyone have an answer to the question? The suggestions about the int types are useful and informative, but I'm having the same issue opening the powerpack namespace in F# interactive.
F# 1.9.6 has a type conversion function so you can do this:
let num = 1000
let num64 = int64(num)
Notice that in this type of conversion, when you reduce the size of a value, the most significant bytes are thrown away, so your data might be truncated:
> let bignum = 4294967297L;;
val bignum : int64
> let myint = int32(bignum);;
val myint : int32
> myint;;
val it : int32 = 1
Note that the functions for converting to each integer type have the same names as the types themselves, and are defined in the library spec (see below). (With the release of the CTP (1.9.6.2), a lot of the library and the namespaces changed a bit compared to previous releases, but it will probably be more 'stable' moving forward.)
http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.Operators.html