operator and operand don't agree error in this simple function - ml

Consider this definition:
fun abs(x:int):int = (x*x)/(~x);
which should return the absolute value of the input. But when the function is called, I get this error:
Error: operator and operand don't agree [tycon mismatch]
operator domain: real * real
operand: int * int
in expression:
x * x / ~ x
What am I doing wrong? Didn't I use :intcorrectly?
Thanks

In SML, / is division on reals. For integers, you need to use div.
> fun abs x = x*x div ~x;
val abs = fn : int -> int

Related

If I have one variable as int, and use it for calculating other of type float, why is result shown as rounded-down float?

I'm doing an equation solver. The code goes like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Equation solver of type ax + by = 0, for y\n");
int a, b, x;
float y;
printf("Enter value of a as integer: ");
scanf("%d", &a);
printf("Enter value of b as integer: ");
scanf("%d", &b);
printf("Enter value of x as integer: ");
scanf("%d", &x);
y = a*x/b; //We have equation ax + by = 0, from that: ax = by, and that is: y = ax/b
printf("Solution for y of equation: %dx + %dy = 0, for x = %d, is: %.2f", a, b, x, y);
return 0;
}
When I enter a = 3, b = 5 and x = 3, the output is supposed to be 1.80, but I get 1.00. Why is this? Wouldn't expression a*x/b be converted into type of float? I'm just beginner and we only mentioned type conversion with our professor, maybe I got it wrong?
Wouldn't expression a*x/b be converted into type of float?
The result of that expression gets converted to float before being assigned to y. Since each operand has type int, the math is done with that type.
Specifically, a*x and b both have type int, so integer division is performed which truncates the fractional part.
If you cast one of the variables to type float, then floating point division will be performed.
y = (float)a*x/b;
In a*x/b all variables are ints so it's a pure integer calculation.
If you cast one of the first operands used to float, the other will also be implicitly converted to float
y = (float) a * x / b;
More about what implicit conversions there are can be found here:
Implicit conversions
Broken down according to operator precedence:
Precedence
Operator
Description
Associativity
3
* / %
Multiplication, division, and remainder
Left-to-right
14
=
Simple assignment
Right-to-left
y = a*x/b; // with a = 3, b = 5 and x = 3
According to operator precedence, a*x will be performed first and as can be read in the Usual arithmetic conversions chapter on Implicit conversions:
"The arguments of the following arithmetic operators [*, /, %, +, -, ...] undergo implicit conversions for the purpose of obtaining the common real type, which is the type in which the calculation is performed"
If "both operands are integers. Both operands undergo integer promotions". Since both a and x are int - no promotion is necessary and the common type is therefore int and the calculation is done using ints:
3 * 3 => 9
Next according to operator precedence comes the result of a*x divided by b. Again, b is an int and 9 is an int so the same procedure as above gives us int as the common type.
9 / 5 => 1
The last step according to operator precedence is the simple assignment y = 1. In the chapter "Conversion as if by assignment" we can read:
"In the assignment operator, the value of the right-hand operand is converted to the unqualified type of the left-hand operand."
This means that it's only now that the result of the calculation, 1, becomes 1.f (float)
1 => 1.f
and that's what's assigned to y.
By converting a to float, like in y = (float) a * x / b;, you can follow the rules for finding the common type and see that x will be converted to float and then b, so the calculation becomes 3.f * 3.f / 5.f and the result will be 1.8f.
If you are sure that a * x will not cause integer overflow (~produce a value that is too large or small to store in an int), you can delay the conversion until the division:
y = a * x / (float) b;
It will now do an integer multiplication and only then will the result of that multiplication be converted to float and divided by 5.f, as if done like so:
y = (float) (3 * 3) / 5.f;

the code does not work error: called object is not a function or function pointerr

#include <math.h>
#include <stdio.h>
int main() {
double x0, x, eps, dx, r;
x0 = 0.60000;
x = x0;
eps = 0.0001;
do {
r = x + pow(x, 1 / 2) + pow(x, 1 / 3) - 2.5;
dx = (r / (1 - 1 / 2 (x , -1 / 2) + 1/3 (x, -1 / 3)));
x = (x - dx);
} while ((abs(dx)) > eps);
printf("%f %f\n", x, r);
return 0;
}
*error: called object is not a function or function pointer *
the code does not work, what needs to be done to make everything right
You have tons of syntax and semantic errors:
pow(x, 1 / 2)
Here 1/2 does integer division which means that the resulting 0.5 is chopped to 0.
To get floating point results you must ensure that at least one operand is a floating type like 1.0/2.
Then you have a similar piece
1/2(x,-1/2)
Again, due to integer division -1/2 evaluates to 0.
Furthermore you are missing some operator before the brackets.
That means the compiler expects some function call.
But 2 is not a function. That is probably the place where you get your error message.
If you use , in other situations than a parameter list or variable definition list, it is taken as a "comma operator" that evaluates to the second operand. That means (x,-1/2)evaluates to (-1/2) which again evaluates to 0.
In this case I have no idea what you want to achieve with that expression and cannot give some fix for that.
Finally, you use a function that is not suitable for floating point numbers and don't provide a prototype for it as well:
abs(dx)
You should use fabs instead.
Usage of abs is also broken because it requires header stdlib.h which you do not include.

What does the line seed[0] *= 16807 do

in the following code:
float sfrand( int *seed )
{
float res;
seed[0] *= 16807;
*((unsigned int *) &res) = ( ((unsigned int)seed[0])>>9 ) | 0x40000000;
return( res-3.0f );
}
source: http://iquilezles.org/www/articles/sfrand/sfrand.htm
seed[0] is same as *seed, that is the first integer (possibly the only one, if it doesn't point to an array) pointed to by seed pointer.
*= operator is "assignment by product" operator,
seed[0] *= 16807; is same as
*seed = *seed * 16807;, which is what the line you ask about does.
The whole function is a simple algorithm to generate pseudo-random numbers, it seems. The purpose of modifying the seed is, that next call will produce a different pseudo-random number.
The seed[0] *= 16807; line is just a shortcut for seed[0] = seed[0] * 16807;
Here's a list of similar constructs: https://www.programiz.com/c-programming/c-operators
*= is a composite operator for multiplication. In this operator, the result that left operand multiplies to right operand will be stored with left operand. So in this statement seed[0] *= 1680;, left operand is seed[0], right operand is 1680. After this statement is executed, seed[0] will be equal to seed[0] * 1680. The is a similar statement for it:
seed[0] = seed[0] * 1680;
We have some composite operators: +=, -=,/=, ... that are working in the same behavior.

Why this conditional expression has the size of a float?

I expect the output to be "short int" but the output is "float".
#include <stdio.h>
int main(void)
{
int x = 1;
short int i = 2;
float f = 3;
if (sizeof((x == 2) ? f : i) == sizeof(float))
printf("float\n");
else if (sizeof((x == 2) ? f : i) == sizeof(short int))
printf("short int\n");
}
You expect (x == 2) ? f : i to have a type based on the value of x. But that is not how the C type system operates. The conditional operator is an expression, and all* expressions in C have a fixed type at compile time. It is this type that sizeof operates on. The value of the expression will depend on the value of x, but the type depends on f and i alone.
In this case, the type is the determined by the usual arithmetic conversions, which nominate float as the type of the result, same as if you had written f + i, where the result would unsurprisingly be a float too.
(*) - VLA's produce exemptions to this rule, but your question is not about one, so it's irrelevant.
You are asking the compiler to compute the size of (x == 2) ? f : i and that expression is a float.
Remember that sizeof is a compile-time operator, and that the ?: ternary conditional operator will have as type something which is convertible from both the "then" and the "else" case.
For details, refer to some C reference and to the C11 standard n1570

sizeof of the conditional operator's value ?:

#include <stdio.h>
int main()
{ int x = 1;
short int i = 2;
float f = 3;
if(sizeof((x == 2) ? f : i) == sizeof(float))
printf("float\n");
else if (sizeof((x == 2) ? f : i) == sizeof(short int))
printf("short int\n");
}
Here the expression ((x == 2) ? f : i) evaluates to i which is of type short int.. size of short int =2 whereas sizeof float is 4 byts.output should be "short int" but i m getting output "float"
Here the expression ((x == 2) ? f : i) evaluates to i which is of type short int
This is not how usual arithmetic conversions work in C. The second and third operands of ? : are first converted to a common type, and that type is the type of the result of the expression. And also that type will not in any case be smaller than int, because of promotions.
This is all described in clause 6.3.1 Arithmetic operands of the C11 standard, which is slightly too long to cite here.
sizeof is a compile-time operator, so it cannot evaluate x==2. It evaluates the type of the ternary expression, which in this case is float, via a conversion to a common type (the second and third operands of the ternary expression must be of the same type, and the int gets converted to float.)

Resources