First, I want to say that this is just a simple code, it's an example and I am studying for a exam.
public class TOblik
{
public int povrsina = 0;
public TVrsta vrsta = 0;
public TOblik(TVrsta a)
{
}
}
public enum TVrsta
{
Kvadrat,
Krug
}
public class A
{
public static double Dodaj(TOblik o, TVrsta v, double r = 0)
{
if (v == TVrsta.Kvadrat)
{
return o.povrsina + r * r;
}
else
{
o.vrsta = v;
return o.povrsina;
}
}
static void Main(string[] args)
{
TOblik oblik = new TOblik(TVrsta.Kvadrat);
double vrednost = 10;
byte broj = 5;
TVrsta vrsta = TVrsta.Krug;
Dodaj(oblik, vrsta, broj);
Console.WriteLine();
Console.ReadLine();
}
}
What I don't get is why is this code working. The method Dodaj last parameter is double, but it is accepting when I forward broj (which type is byte).
C# has implicit casts: data of some types can convert to data in other types without mentioning the conversion (explicit conversions also exist like for instance byte a = (byte) b; ). Usually implicit casts can only be done when the "target type" is more general and thus can handle all values of the source type.
As you can read in the documentation:
The following table shows the predefined implicit numeric conversions.
Implicit conversions might occur in many situations, including method
invoking and assignment statements.
(...)
From To
------------------------------------------------------------------------
... ...
byte short, ushort, int, uint, long, ulong, float, double, or decimal
... ...
The documentation also warns that conversion from int to for instance float might result in precision loss. So one always has to be a bit careful with these.
You can see that this conversion happens in the csharp interactive shell:
csharp> byte a = 10;
csharp> double b = a;
csharp> b
10
Related
When the int variable is more than 10 digits, an error occurs and the number becomes negative.
Why is this happening and how can I solve the problem?
This is my code:
UnityWebRequest www = new UnityWebRequest("https://api.hypixel.net/skyblock/bazaar");
www.downloadHandler = new DownloadHandlerBuffer();
yield return www.SendWebRequest();
JSONNode itemsData = JSON.Parse(www.downloadHandler.text);
unixtimeOnline = itemsData2["lastUpdated"];
Debug.Log(unixtimeOnline);
// output -2147483648
tl;dr
Simply use ulong instead of int for unixtimeOnline
ulong unixtimeOnline = itemsData2["lastUpdated"];
What happened?
As was already mentioned int (or also System.Int32) has 32 bits.
The int.MaxValue is
2147483647
no int can be higher than that. What you get is basically a byte overflow.
From the JSON.Parse I suspect you are using SimpleJson
and if you have
int unixtimeOnline = itemsData2["lastUpdated"];
it will implicitly use
public static implicit operator int(JSONNode d)
{
return (d == null) ? 0 : d.AsInt;
}
which uses AsInt
public virtual int AsInt
{
get { return (int)AsDouble; }
set { AsDouble = value; }
}
which is a problem because a double can hold up to
so when you simply do
double d = 2147483648.0;
int example = (int)d;
you will again get
-2147483648
What you want
You want to use a type that supports larger numbers. Like e.g.
long: goes up to
9,223,372,036,854,775,807
and is actually what system time ticks are usually stored as (see e.g. DateTime.Ticks
or actually since your time is probably never negative anyway directly use the unsigned ones
ulong: goes up to
18,446,744,073,709,551,615
Solution
Long store short: There are implicit conversion for the other numeric values so all you need to do is use
ulong unixtimeOnline = itemsData2["lastUpdated"];
and it will use AsUlong instead
public static implicit operator ulong(JSONNode d)
{
return (d == null) ? 0 : d.AsULong;
}
which now correctly uses
public virtual ulong AsULong
{
get
{
ulong val = 0;
if (ulong.TryParse(Value, out val))
return val;
return 0;
}
set
{
Value = value.ToString();
}
}
As the comment says you will need to use a long variable type
I'm developing a class library with C#, .NET Framework 4.7.1 and Visual Studio 2017 version 15.6.3.
I have this code:
public static T Add<T, K>(T x, K y)
{
dynamic dx = x, dy = y;
return dx + dy;
}
If I use with this code:
genotype[index] = (T)_random.Next(1, Add<T, int>(_maxGeneValue, 1));
genotype is a T[].
I get the error:
Argument 2: cannot convert from 'T' to 'int'
But if I change the code:
public static K Add<T, K>(T x, K y)
{
dynamic dx = x, dy = y;
return dx + dy;
}
I get the error:
CS0030 Cannot convert type 'int' to 'T'
When I get this error T is a byte.
How can I fix this error? Or maybe I can change random.Next to avoid doing the Add.
The minimal code:
public class MyClass<T>
{
private T[] genotype;
private T _maxGeneValue;
public void MinimalCode()
{
Random _random = new Random();
genotype = new T[] {0, 0, 0};
int index = 0;
_maxGeneValue = 9;
genotype[index] = (T)_random.Next(1, Add<T, int>(_maxGeneValue, 1));
}
}
It is a generic class because the genotype array can be of bytes or integers or floats. And I use the random to generate random values between 1 and _maxGeneValue. I need to add one because the maxValue in Random is exclusive.
The elements in the genotype array could any of the built-in types, as far as I know numerics. And I don't want to create a class for each of the types I'm going to use (and use the biggest one in array declaration, i.e. long[], is a waste of space).
T is a generic class because the genotype array can be of bytes or integers or floats
That is not what generic means. Generic means that there is an unbound number of valid types. You only have 3, that does not qualify for a generic solution at all.
A major lesson learned here is: if the type system fights against you, stop and think it over, you are probably doing something wrong; the cast to dynamic should have been a huge red flag.
The solution to your problem is to simply overload. You have 3 valid types: byte, int and float. I'm guessing you want to avoid losing information so the following should hold:
If adding integral types, use the "smallest" possible type (this can be potentially "unsafe" in the sense that it can overflow).
If one of the operands is a float, use floating point arithmetics.
OK, so we need:
public byte Add(byte left, byte right) { .... }
public int Add(int left, int right) { .... }
public float Add(float left, float right) { .... }
And now think about something else: do you want the sum of two bytes to overflow? Or do you want to return an int? What I mean is: what should byte 250 + byte 10 return? A byte or an int? If its an int, remove the first overload. Now think about the same issue with ints. If you don't want any overflows, then remove the second overload too.
For example, does an operator exist to handle this?
float Result, Number1, Number2;
Number1 = 2;
Number2 = 2;
Result = Number1 (operator) Number2;
In the past the ^ operator has served as an exponential operator in other languages, but in C# it is a bit-wise operator.
Do I have to write a loop or include another namespace to handle exponential operations? If so, how do I handle exponential operations using non-integers?
The C# language doesn't have a power operator. However, the .NET Framework offers the Math.Pow method:
Returns a specified number raised to the specified power.
So your example would look like this:
float Result, Number1, Number2;
Number1 = 2;
Number2 = 2;
Result = Math.Pow(Number1, Number2);
I stumbled on this post looking to use scientific notation in my code, I used
4.95*Math.Pow(10,-10);
But afterwards I found out you can do
4.95E-10;
Just thought I would add this for anyone in a similar situation that I was in.
There is a blog post on MSDN about why an exponent operator does NOT exists from the C# team.
It would be possible to add a power
operator to the language, but
performing this operation is a fairly
rare thing to do in most programs, and
it doesn't seem justified to add an
operator when calling Math.Pow() is
simple.
You asked:
Do I have to write a loop or include
another namespace to handle
exponential operations? If so, how do
I handle exponential operations using
non-integers?
Math.Pow supports double parameters so there is no need for you to write your own.
The lack of an exponential operator for C# was a big annoyance for us when looking for a new language to convert our calculation software to from the good ol' vb6.
I'm glad we went with C# but it still annoys me whenever I'm writing a complex equation including exponents. The Math.Pow() method makes equations quite hard to read IMO.
Our solution was to create a special DoubleX class where we override the ^-operator (see below)
This works fairly well as long as you declare at least one of the variables as DoubleX:
DoubleX a = 2;
DoubleX b = 3;
Console.WriteLine($"a = {a}, b = {b}, a^b = {a ^ b}");
or use an explicit converter on standard doubles:
double c = 2;
double d = 3;
Console.WriteLine($"c = {c}, d = {d}, c^d = {c ^ (DoubleX)d}"); // Need explicit converter
One problem with this method though is that the exponent is calculated in the wrong order compared to other operators. This can be avoided by always putting an extra ( ) around the operation which again makes it a bit harder to read the equations:
DoubleX a = 2;
DoubleX b = 3;
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + a ^ b}"); // Wrong result
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + (a ^ b)}"); // Correct result
I hope this can be of help to others who uses a lot of complex equations in their code, and maybe someone even has an idea of how to improve this method?!
DoubleX class:
using System;
namespace ExponentialOperator
{
/// <summary>
/// Double class that uses ^ as exponential operator
/// </summary>
public class DoubleX
{
#region ---------------- Fields ----------------
private readonly double _value;
#endregion ------------- Fields ----------------
#region -------------- Properties --------------
public double Value
{
get { return _value; }
}
#endregion ----------- Properties --------------
#region ------------- Constructors -------------
public DoubleX(double value)
{
_value = value;
}
public DoubleX(int value)
{
_value = Convert.ToDouble(value);
}
#endregion ---------- Constructors -------------
#region --------------- Methods ----------------
public override string ToString()
{
return _value.ToString();
}
#endregion ------------ Methods ----------------
#region -------------- Operators ---------------
// Change the ^ operator to be used for exponents.
public static DoubleX operator ^(DoubleX value, DoubleX exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(DoubleX value, double exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(double value, DoubleX exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(DoubleX value, int exponent)
{
return Math.Pow(value, exponent);
}
#endregion ----------- Operators ---------------
#region -------------- Converters --------------
// Allow implicit convertion
public static implicit operator DoubleX(double value)
{
return new DoubleX(value);
}
public static implicit operator DoubleX(int value)
{
return new DoubleX(value);
}
public static implicit operator Double(DoubleX value)
{
return value._value;
}
#endregion ----------- Converters --------------
}
}
Since no-one has yet wrote a function to do this with two integers, here's one way:
private static long CalculatePower(int number, int powerOf)
{
long result = number;
for (int i = 2; i <= powerOf; i++)
result *= number;
return result;
}
Alternatively in VB.NET:
Private Function CalculatePower(ByVal number As Integer, ByVal powerOf As Integer) As Long
Dim result As Long = number
For i As Integer = 2 To powerOf
result = result * number
Next
Return result
End Function
CalculatePower(5, 3) ' 125
CalculatePower(8, 4) ' 4096
CalculatePower(6, 2) ' 36
For what it's worth I do miss the ^ operator when raising a power of 2 to define a binary constant. Can't use Math.Pow() there, but shifting an unsigned int of 1 to the left by the exponent's value works. When I needed to define a constant of (2^24)-1:
public static int Phase_count = 24;
public static uint PatternDecimal_Max = ((uint)1 << Phase_count) - 1;
Remember the types must be (uint) << (int).
I'm surprised no one has mentioned this, but for the simple (and probably most encountered) case of squaring, you just multiply by itself.
float someNumber;
float result = someNumber * someNumber;
A good power function would be
public long Power(int number, int power) {
if (number == 0) return 0;
long t = number;
int e = power;
int result = 1;
for(i=0; i<sizeof(int); i++) {
if (e & 1 == 1) result *= t;
e >>= 1;
if (e==0) break;
t = t * t;
}
}
The Math.Pow function uses the processor power function and is more efficient.
It's no operator but you can write your own extension function.
public static double Pow(this double value, double exponent)
{
return Math.Pow(value, exponent);
}
This allows you to write
a.Pow(b);
instead of
Math.Pow(a, b);
I think that makes the relation between a and b a bit clearer + you avoid writing 'Math' over and over again.
I am writing a simple program in which I have defined a function which accepts certain type of argument , now new requirement I got has same procedures to be done which I had already in written in earlier function , but this time it should on different type of argument.I am not able to call straight way this same function for two different types of arguments. So my question is how I should modify my function to behave in such a way. I am hoping that it is possible. I would like something as ,I have function like Sum(int 1,int j) now I would like to use same function for double type arguments.
This is called overloading. What you can do is simply write two functions:
public double Sum(int 1, int j)
public double Sum(double 1, double j)
And your program will call the appropriate one based on the arguments you pass to it.
Simple with generics
T Sum<T>(T i,T j) { ... }
However, you won't be able to do i+j or anything, so it depends.
Why don't you define a method with double as parameter type and later you can call it for integer values as well.
private double Sum(double a, double b)
{
return a+b;
}
and later you can call it like:
int a = 1;
int b = 2;
int Sum = (int) Sum(a,b);
Since an integer can be passed to a double type parameter. But if your method involves complex calculation then you are better of with multiple overloads of the Sum method with different types.
In .NET there is no type encompassing different numeric types. So you need two overloads of the same method, one that takes int arguments, one that takes double arguments.
You declare a new method with the same amount of parameters but different types.
public Int32 Sum(Int32 i, Int32 j)
{
return i + j;
}
public Double Sum(Double i, Double j)
{
return i + j;
}
So you have a method that takes int parameters
public int Sum(int val1,int val2)
{
return val1 + val2;
}
Now you need a method that takes doubles:
public double Sum(double val1,double val2)
{
return val1 + val2;
}
If you want a generic class which supports all "numeric" types you can have a look here:
http://www.codeproject.com/Articles/33617/Arithmetic-in-Generic-Classes-in-C
You can write GENERIC METHODS for different datatypes.
check this Link
Look more into this link. It shows how o create a function that can handle several datatypes.
int a = 2, b = 3;
double c = 2.345, d = 3.45;
object inta = a, intb = b;
object doublec = c, doubled = d;
Console.WriteLine(Sum(inta, intb).ToString());
Console.WriteLine(Sum(doublec, doubled).ToString());
public object Sum(object a, object b)
{
object sum = null;
if (a.GetType().ToString() == "System.Int32" && b.GetType().ToString() == "System.Int32")
{
sum = Convert.ToInt32(a.ToString()) + Convert.ToInt32(b.ToString());
}
if (a.GetType().ToString() == "System.Double" && b.GetType().ToString() == "System.Double")
{
sum = Convert.ToDouble(a.ToString()) + Convert.ToDouble(b.ToString());
}
return sum;
}
In C#, when defining a public method like:
public int myMethod(String someString)
{
//code
}
What does the int indicate apart from the type integer? What confuses me is that the method is using a String as arguments in this case.
It is the return type of the method. In this case a 32-bit signed integer with a range of
-2,147,483,648 .. +2,147,483,647
It corresponds to the .NET type System.Int32. int is just a handy C# alias for it.
You would return a value like this
public int Square(int i)
{
return i * i;
}
And you could call it like this
int sqr = Square(7); // Returns 49
// Or
double d = Math.Sin(Square(3));
If you do not need the return value, you can safely ignore it.
int i;
Int32.TryParse("123", out i); // We ignore the `bool` return value here.
If you have no return value you would use the keyword void in place of the type. void is not a real type.
public void PrintSquare(int i)
{
Console.WriteLine(i * i);
}
And you would call it like this
PrintSquare(7);
The method in your example accepts a string as input parameter and returns an int as result. A practical example would be a method that counts the number of vowels in a string.
public int NumberOfVowels(string s)
{
const string vowels = "aeiouAEIOU";
int n = 0;
for (int i = 0; i < s.Length; i++) {
if (vowels.Contains(s[i])) {
n++;
}
}
return n;
}
It stands for "integer", and it means the method returns an integer number of 32 bits, also known in C# as Int32.
As previously stated, it's what the method returns.
For example:
public string x()
{
return 5;
}
Would error. 5 is definitely not a string!
public int x()
{
return 5;
}
Would be correct; since 5 can be considered an int (Short for integer, which is, basically, just a number which cannot have a decimal point. There's also float, double, long and decimal, which are worth reading about)
There must be no way of it not returning, for example, if you do:
public int x()
{
if (false)
{
return 5;
}
}
It will error because if the expression is false (It is of course) it won't be returning an int, it won't return anything.
If you use the keyword void, it means it does not return anything. Ex:
public void x()
{
someFunction("xyz");
}
It's fine that it doesn't return as it's a void method.
I don't think you're new to programming judging by your reputation, but just in case, when you return something you pass it back from the method, for example:
int x;
public int seven()
{
return 7;
}
x = seven();
x will become the return value of the function seven.
Note that the 'dynamic' type works here:
public dynamic x(int x, int y)
{
if (x == y)
{
return "hello";
}
return 5
}
But if you're new to C# don't get caught up in dynamic typing just yet. :)
It is the type of the return value.
Everyone is correct here but the definition from msdn:
"Int32 is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant. The .NET Framework also includes an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295."
Found here on MSDN: Int32 Structure
I suggest you read the documentation found in the link above. It is extremely useful.