Function in C returns initial value of a variable - absolute

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.

Related

How to convert int to double and vice-versa when parsing using num.parse?

Minimal reproducible code:
void main() {
print(foo<int>('1'));
print(foo<double>('1.0'));
print(foo<double>('1'));
print(foo<int>('1.0'));
}
T foo<T extends num>(String s) {
final res = num.parse(s);
return (T == double ? res.toDouble() : res.toInt()) as T;
}
As you can see I'm manually handling the types. Is there any better way to do it?
I don't see a much better solution. You have a function which changes behavior entirely based on the type argument. Since all you can do with a type argument is subtype-checks, or comparing it to a constant type literal, you need to do something like that.
I'd prefer subtype-checks, because that also allows promotion, but for something limited like this, where there are only four possible types for T, checking Type object equality can also work. There'll just need to be at least one as T before returning.
Either approach also only works for type hierarchies which are finite, and you account for all the possible types. Even here, the current code is not covering <num> and <Never> which are also valid type arguments for the bound num. So, be vigilant.
Maybe, using subtype checks for promotion:
T parse<T extends num>(String source) {
var value = num.parse(source);
if (value is T) return value;
// T is not `num`.
num d = value.toDouble();
if (d is T) return d; // T was double.
try {
num n = value.toInt(); // Can fail for Infinity/NaN
if (n is T) return n; // T was int
} catch (_) {
// T was `int` after all, so throwing was correct.
if (1 is T) rethrow; // T was int, but the input was not valid.
}
// T was neither num, double, nor int, so must be `Never`.
throw ArgumentError.value(T, "T", "Must not be Never");
}
Or. using Type object equality:
T parse<T extends num>(String source) {
var value = num.parse(source);
switch (T) {
case num: return value as T;
case int: return value.toInt() as T;
case double: return value.toDouble() as T;
default:
throw ArgumentError.value(T, "T", "Must not be Never");
}
}

Truthy and falsy values in Dart programming language

I just stand in front of a very weird part in dart, I didn't find an answer on the internet, No truthy and falsy values in dart?!
for example,
const x = "foo";
void main(){
if(x){
print("x is set")
}
}
In JavaScript we do this things very easily, how can I do that in Dart?!
Dart is a statically typed language, so x is a String, and you can't check if a string is true or false.
if you want to check if x has a value or not, you can do the following
String x = 'hi';
if (x?.isNotEmpty ?? false) {
print("x is set");
}
After some researches, I've found that in order to check for a dynamiclly assigned variable, where in case you're not sure if the variable will be set to a number or a string for example, you need to check if the variable is not equal to null.
For example:
void main(){
var a;
if(true){
a = "The variable is set to string";
}
else if(false){
a = 12; //the variable is set to a number
}
//Now, to check:
if(a != null){
print("A is set, WOW Dart is working! I thought it's garbage!");
}
}
In case the both statements are false, the variable will still be a null.

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

Using an 'is' expression when the right-hand operand is a variable?

I am trying to write a function that takes two arguments: givenType and targetType. If these two arguments match, I want givenType to be returned, otherwise null.
For this objective, I am trying to utilize Dart's is expression (maybe there is a better way to go about it, I am open to suggestions). Initially, I thought it would be as simple as writing this:
matchesTarget(givenType, targetType) {
if (givenType is targetType) {
return givenType;
}
return null;
}
But this produces an error:
The name 'targetType' isn't a type and can't be used in an 'is'
expression. Try correcting the name to match an existing
type.dart(type_test_with_non_type)
I tried looking up what satisfies an is expression but cannot seem to find it in the documentation. It seems like it needs its right-hand operand to be known at compile-time (hoping this is wrong, but it does not seem like I can use a variable), but if so, how else can I achieve the desired effect?
I cant guess the purpose of the function (or the scenario where it would be used, so if you can clarify it would be great). First of all, I don't know if you are passing "types" as arguments. And yes, you need to specify in compile time the right hand argument of the is function.
Meanwhile, if you are passing types, with one change, you can check if the types passed to your function at runtime.
matchesTarget(Type givenType, Type targetType) {
print('${givenType.runtimeType} ${targetType.runtimeType}');
if (givenType == targetType) {
return givenType;
}
return null;
}
main(){
var a = int; //this is a Type
var b = String; //this is also a Type
print(matchesTarget(a,b)); //You are passing different Types, so it will return null
var c = int; //this is also a Type
print(matchesTarget(a,c)); //You are passing same Types, so it will return int
}
But if you are passing variables, the solution is pretty similar:
matchesTarget(givenVar, targetVar) {
print('${givenVar.runtimeType} ${targetVar.runtimeType}');
if (givenVar.runtimeType == targetVar.runtimeType) {
return givenVar.runtimeType;
}
return null;
}
main(){
var a = 10; //this is a variable (int)
var b = "hello"; //this is also a variable (String)
print(matchesTarget(a,b)); //this will return null
var c = 12; //this is also a variable (int)
print(matchesTarget(a,c)); //this will return int
}
The Final Answer
matchesTarget(givenVar, targetType) {
print('${givenVar.runtimeType} ${targetType}');
if (givenVar.runtimeType == targetType) {
return givenVar;
}
return null;
}
main(){
var a = 10; //this is a variable (int)
var b = String; //this is a type (String)
print(matchesTarget(a,b)); //this will return null because 'a' isnt a String
var c = int; //this is also a type (int)
print(matchesTarget(a,c)); //this will return the value of 'a' (10)
}
The as, is, and is! operators are handy for checking types at runtime.
The is operator in Dart can be only used for type checking and not checking if two values are equal.
The result of obj is T is true if obj implements the interface specified by T. For example, obj is Object is always true.
See the below code for an example of how to use the is operator
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
Even the error message that you're getting says that
The name 'targetType' isn't a type and can't be used in an 'is'
expression.
So the bottomline is that you can use is only for checking if a variable or value belongs to a particular data type.
For checking equality, you can use the == operator if comparing primitive types, or write your own method for comparing the values. Hope this helps!

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

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;

Resources