If I do
final x = (2 == 2.0);
Then x is true.
But if I do
const x = (2 == 2.0);
Then x is false.
I would expect both to be true based on the docs:
If one operand is a double and the other is an int, they are equal if the double has an integer value (finite with no fractional part) and identical(doubleValue.toInt(), intValue) is true.
What's going on here?
Related
For illustration purposes, I want to overload unary prefix and postfix -- operators. However, the editor (VSCode) gives me a red wavy line as follows. Adding #override does not help as well.
I cannot find a list of overloadable operators in Dart. Is there such a list available?
Example
import 'dart:math';
class Point {
double _x, _y;
Point(this._x, this._y);
Point.Origin()
: _x = 0,
_y = 0;
double DistanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
double get x => _x;
double get y => _y;
set x(double _) => _x = _;
set y(double _) => _y = _;
Point operator -() => Point(-x, -y);
//Point operator -(p) => Point(--x,--y) ;
#override
Point operator --() => Point(x-1,y-1);
#override
Point operator +() => this;
//Point operator +(double r) => Point(x+r,y+r);
Point operator +(Point r) => Point(x + r.x, y + r.y);
}
You have the full list of supported operators listed here
page 30:
The following names are allowed for user-defined operators: ‘<’, ‘>’, ‘<=’,
‘>=’, ‘==’, ‘-’, ‘+’, ‘/’, ‘˜/’, ‘*’, ‘%’, ‘|’, ‘ˆ’, ‘&’, ‘<<’, ‘>>’, ‘>>>’, ‘[]=’, ‘[]’, ‘˜’.
So I am afraid that you cannot override -- or ++ operator.
If you are only interested into a quick way to decrement or increment your point
I found a little hack for you if you are okay to lose some operators:
import 'dart:math';
class Point {
double x, y;
Point(this.x, this.y);
Point.origin()
: x = 0,
y = 0;
double distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
Point operator -(Point r) => Point(x-r.x, x-r.y);
Point operator +(Point r) => Point(x + r.x, y + r.y);
// bye bye shift operations
Point operator >>(Point r)=> Point(x-1, y-1);
Point operator <<(Point r)=> Point(x+1, y+1);
#override toString() {
return "Point ($x,$y)";
}
}
And use this way:
Point a = new Point(3,5);
a>>=(a); // a(x--,y--);
print(a);
a<<=(a); // a(x++,y++);
print(a);
Output:
I/flutter (10464): Point (2.0,4.0)
I/flutter (10464): Point (3.0,5.0)
PS: no need for getters and setters in Dart ;)
Edit: For your last question in comment:
Point operator +(Point r) => Point(x, y);
And use like:
a+(a);
Note that for minus you will not need to provide an argument (arity is 0 means 0 arg)
It is a compile-time error if the arity of a user-declared operator with one of the names: ‘<’, ‘>’, ‘<=’, ‘>=’, ‘==’, ‘-’, ‘+’, [...] is not 1. It is a compile-time error if the arity of the user-declared operator ‘-’ is not 0 or 1.
How do I make a function scale(), that multiplies a float and a vector. It has to use this library shown here? I think it's called library, sorry if that is wrong.
/// Multiplication of a float and a vector
val scale : float -> float * float -> float * float
Spent 4 hours trying to figure it out.
My assignment (Data sciences 3rd week) is, I have a signature-file containing a 2D vector library and I need to make functions out of it using that library.
/// A 2D vector library
/// Vectors are represented as pairs of floats module vec2d
/// The length of a vector
val len : float * float -> float
/// The angle of a vector
val ang : float * float -> float
/// Multiplication of a float and a vector
val scale : float -> float * float -> float * float
/// Addition of two vectors
val add : float * float -> float * float -> float * float
/// Dot product of two vectors
val dot : float * float -> float * float -> float
Currently I have:
// LENGTH OF A VECTOR
// val len : float * float -> float
let len (x: float, y: float) =
sqrt(x**2.0 + y**2.0)
// ANGLE OF A VECTOR
// val ang : float * float -> float
let ang (x: float, y: float) =
Math.Atan2(y, x)
// MULTIPLICATION OF A FLOAT AND A VECTOR
// val scale : float -> float * float -> float * float
let scale () =
None
/// ADDITION OF TWO VECTORS
// add : float * float -> float * float -> float * float
let add (xy1: float, xy2: float) =
None
/// DOT PRODUCT OF TWO VECTORS
// dot : float * float -> float * float -> float
let dot (xy1: float, xy2: float) =
None
Any kind of help/hint would be really helpful! I'm stuck!
Is this what you're looking for?
let scale n (x: float, y: float) =
n*x, n*y
This multiplies each of the values in the vector tuple (x,y) with the float n.
Newbie question:
void main () {
int A = 1;
int B = 2;
double C = A / B;
stdout.printf("C value is: %g\n", C);
}
This prints: "C value is: 0"
void main () {
int A = 1;
double B = 2;
double C = A / B;
stdout.printf("C value is: %g\n", C);
}
This prints: "C value is: 0.5"
I don't understand the reason why the result is not 0.5 in both cases.
The division operation is performed on two integers, so the result is an integer. The fact that you assign it to a double afterwards doesn't change that.
What you're doing in your question, with the implicit conversions made explicit, is
int A = 1;
int B = 2;
double C = (double) (A / B);
However, if you want to perform the division operation using doubles you have to explicitly cast at least one of the operands to double:
int A = 1;
int B = 2;
double C = ((double) A) / B;
For the rules concerning arithmetic operations, see the arithmetic expressions section of the Vala Manaual. The relevant bit:
If both operands are of integer types, then the result will be the quotient only of the calculation (equivalent to the precise answer rounded down to an integer value.) If either operand is of a floating point type, then the result will be as precise as possible within the boundaries of the result type (which is worked out from the basic arithmetic type rules.)
The following produces the below error:
int calc_ranks(ranks)
{
double multiplier = .5;
return multiplier * ranks;
}
The return type double is not a int, as defined by the method calc_ranks. How do I round/cast to an int?
Round it using the round() method:
int calc_ranks(ranks) {
double multiplier = .5;
return (multiplier * ranks).round();
}
You can use any of the following.
double d = 20.5;
int i = d.toInt(); // i = 20
int i = d.round(); // i = 21
int i = d.ceil(); // i = 21
int i = d.floor(); // i = 20
You can simply use toInt() to convert a num to an int.
int calc_ranks(ranks)
{
double multiplier = .5;
return (multiplier * ranks).toInt();
}
Note that to do exactly the same thing you can use the Truncating division operator :
int calc_ranks(ranks) => ranks ~/ 2;
I see a lot of answers, but with less description. Hope my answer will add some value.
Lets initalize the variable, and see how it will change with different methods.
double x = 8.5;
toInt()
It truncates the decimal value.
int a = x.toInt();
print(a); // 8
truncate()
It also truncates the decimal value.
int b = x.truncate();
print(b); // 8
round()
It returns the closest integer. It uses half up rounding mode.
int c = x.round();
print(c); // 9
ceil()
It returns the closest integer greater than the value.
int c = x.ceil();
print(c); // 9
floor()
It returns the closest integer smaller than the value.
int c = x.floor();
print(c); // 8
I looked at the answers above and added some more answers to make it a little easier to understand.
double value = 10.5;
Using toInt()
void main(){
double value = 10.5;
var y = value.toInt();
print(y);
print(y.runtimeType);
}
Using round()
The round() method returns the closest integer to the double.
void main(){
double value = 9.6;
var b = value.round();
print(b);
print(b.runtimeType);
}
Using ceil()
The ceil() method returns the smallest integer that is equal or greater than the given double.
void main(){
double value = 9.5;
var d = value.ceil();
print(d);
print(d.runtimeType);
}
Using floor()
The floor() method returns the greatest integer not greater than the given double.
void main(){
double value = 10.9;
var j = value.floor();
print(j);
print(j.runtimeType);
}
Conclusion
We’ve gone through 4 different techniques to convert a double to an integer in Dart and Flutter. You can choose from the method that fits your use case to solve your problem. Flutter is awesome and provides a lot of amazing features.
To convert double to int just this:
division
double01 ~/ double02
PS: The operator x ~/ y is more efficient than (x / y).toInt().
Multiplication, addition and subtraction
(double01 * double02).toInt
(double01 + double02).toInt
(double01 - double02).toInt
Its easy,
(20.8).round()
For String,
double.tryParse(20.8).round()
from string to int ->
if you string in int format like '10'
then use ---->
int.parse(value)
but if string in double format like '10.6'
then use like this ---->
double.parse(value).toInt()
convert double to int
doubleValue.toInt()
Try this!
int calc_ranks(ranks)
{
double multiplier = .5;
return (multiplier * ranks).truncate();
}
class CurrencyUtils{
static int doubletoint(double doublee) {
double multiplier = .5;
return (multiplier * doublee).round();
}
}
----------------------
CustomText( CurrencyUtils.doubletoint(
double.parse(projPageListss[0].budget.toString())
).toString(),
fontSize: 20,
color: Colors.white,
font: Font.QuicksandSemiBold,
),
There's another alternative, you can first cast the double to 'num' datatype and then convert to int using toInt().
double multiplier = .5;
return ((multiplier * ranks) as num).toInt();
The num type is an inherited data type of the int and double types.
You can cast both int and double to num, then cast it again to whatever you want
(double -> use toDouble(), int -> use toInt())
Briefly, I would like to know if it is possible to directly access pixel value
of a CV_32F Mat, through Mat member "uchar* data".
I can do it with no problem if Mat is CV_8U, for example:
// a matrix 5 columns and 6 rows, values in [0,255], all elements initialised at 12
cv:Mat A;
A.create(5,6, CV_8UC1);
A = cv::Scalar(12);
//here I successfully access to pixel [4,5]
uchar *p = A.data;
int value = (uchar) p[4*A.step + 5];
The problem is when I try to do the same operation with the following matrix,
// a matrix 5 columns, 6 rows, values in [0.0, 1.0], all elements initialised at 1.2
cv::Mat B;
B.create(5,6, CV_32FC1);
B = cv::Scalar(1.2);
//this clearly does not work, no syntax error but erroneous value reported!
uchar *p = B.data;
float value = (float) p[4*B.step + 5];
//this works, but it is not what I want to do!
float value = B.at<float>(4,5);
Thanks a lot, Valerio
You can use ptr method which returns pointer to matrix row:
for (int y = 0; y < mat.rows; ++y)
{
float* row_ptr = mat.ptr<float>(y);
for (int x = 0; x < mat.cols; ++x)
{
float val = row_ptr[x];
}
}
You can also cast data pointer to float and use elem_step instead of step if matrix is continous:
float* ptr = (float*) mat.data;
size_t elem_step = mat.step / sizeof(float);
float val = ptr[i * elem_step + j];
Note that CV_32F means the elements are float instead of uchar. The "F" here means "float". And the "U" in CV_8U stands for unsigned integer. Maybe that's why your code doesn't give the right value. By declaring p as uchar*, p[4*B.step+5] makes p move to the fifth row and advance sizeof(uchar)*5, which tend to be wrong. You can try
float value = (float) p[4*B.step + 5*B.elemSize()]
but I'm not sure if it will work.
Here are some ways to pass the data of [i, j] to value:
value = B.at<float>(i, j)
value = B.ptr<float>(i)[j]
value = ((float*)B.data)[i*B.step+j]
The 3rd way is not recommended though, since it's easy to overflow. Besides, a 6x5 matrix should be created by B.create(6, 5, CV_32FC1), I think?