Why in Kotlin bitwise operation is not possible with 4-byte hex and Int?
At the same time, there is no problem in Java
As far as I know, in JVM int takes 4 bytes.
// Kotlin
val num = 0
val n = 0xff000000 or num // <-- 'num' ERROR
// Java
int num = 0;
int n = 0xff000000 | num; // <-- 'num' OK
0xFF000000 is a Long, not an Int. It's outside the Int range since it is using 32 bits to represent a positive number, but Int only uses 31 bits for the number, and one bit for the sign. Any six-digit hexadecimal number where the first digit is greater than 7 requires 32 bits to represent the number, so it is interpreted as a Long.
Kotlin doesn't do implicit number conversions like Java because they can easily lead to obscure bugs. You have to manually convert it to an Int.
val num = 0
val n = 0xff000000.toInt() or num
Related
I have a simple problem, but because this "programming language" I am using is 32-bit and only supports basic functions such as addition, subtraction, multiplication, division, and concatenation (literally that's it), I am having some trouble.
For the input, I have a 16 digit number like so: 3334,5678,9523,4567
I want to then subtract 2 other random 16 digit numbers from this number and check if the first and last digits are 1.
For example, if the two other numbers are 1111,1111,1111,1111 and 1234,5678,9123,4565.
My final number would be: 0988,8888,9288,8891.
Here, the last number is 1, but the first number is 0, so the test would fail.
The issue is with 32-bit systems, there are massive errors due to not enough precision provided by the bits. What are some ways to bypass this issue?
If you're using a language like C or Java you should be able to use a long to create a 64 bit integer. If that's not possible you could divide the numbers into two 32 bit numbers, one to hold the upper half and one to hold the lower half.
Something like this:
//Each half is 8 digits to represent 8 of the 16
//Because of this each half should be less than 100000000
int upperHalf = 33345678;
int lowerHalf = 95234567;
//randomInt represents a function to generate a random
//integer equal to or greater than 0 and less than the
//argument passed to it
int randUpperHalf = randomInt(100000000);
int randLowerHalf = randomInt(100000000);
int lowerHalf = lowerHalf - randLowerHalf;
//If lowerHalf was a negative number you need to borrow from the upperHalf
if (lowerHalf < 0) {
upperHalf = upperHalf - 1;
lowerHalf = lowerHalf + 100000000;
}
upperHalf = upperHalf - randUpperHalf;
//Check that the first and last digits are 1
if ((upperHalf / 100000000) == 1 && (lowerHalf % 10) == 1) {
//The first and last digits are 1
}
Edit: Comments have been added to explain the code better. (lowerHalf % 2) == 1 has been changed to (lowerHalf % 10) == 1 and should now be able to tell if the number ends in a 1.
What is the difference between just giving 1 and giving 1'b1 in verilog code?
The 1 is 32 bits wide, thus is the equivalent of 32'b00000000_00000000_00000000_00000001
The 1'b1 is one bit wide.
There are several places where you should be aware of the difference in length but the one most likely to catch you out is in concatenations. {}
reg [ 7:0] A;
reg [ 8:0] B;
assign A = 8'b10100101;
assign B = {1'b1,A}; // B is 9'b110100101
assign B = {1,A}; // B is 9'b110100101
assign B = {A,1'b1}; // B is 9'b101001011
assign B = {A,1}; // B is 9'b000000001 !!!!
So, what's the difference between, say,
logic [7:0] count;
...
count <= count + 1'b1;
and
logic [7:0] count;
...
count <= count + 1;
Not a lot. In the first case your simulator/synthesiser will do this:
i) expand the 1'b1 to 8'b1 (because count is 8 bits wide)
ii) do all the maths using 8 bits (because now everything is 8 bits wide).
In the second case your simulator/synthesiser will do this:
i) do all the maths using 32 bits (because 1 is 32 bits wide)
ii) truncate the 32-bit result to 8 bits wide (because count is 8 bits wide)
The behaviour will be the same. However, that is not always the case. This:
count <= (count * 8'd255) >> 8;
and this:
count <= (count * 255) >> 8;
will behave differently. In the first case, 8 bits will be used for the multiplication (the width of the 8 in the >> 8 is irrelevant) and so the multiplication will overflow; in the second case, 32 bits will be used for the multiplication and so everything will be fine.
1'b1 is an binary, unsigned, 1-bit wide integral value. In the original verilog specification, 1 had the same type as integer. It was signed, but its width was unspecified. A tool could choose the width base on its host implementation of the int type.
Since Verilog 2001 and SystemVerilog 2005, the width of integer and int was fixed at 32-bits. However, because of this original unspecified width, and the fact that so many people write 0 or 1 without realizing that it is now 32-bits wide, the standard does not allow you to use an unbased literal inside a concatenation. {A,1} is illegal.
How can I split a Long (64bit) into two Integer (32bit) in Kotlin?
I've tried something like this but it doesn't seem to be doing it:
val id = Integer.MAX_VALUE.toLong() + 2000
val a = id.toInt()
val b = (id shr 32).toInt()
Everything is working fine. Note that Integer.MAX_VALUE is 0x7FFFFFFF, when you add 2000, it becomes 0x800007CF, which is still within 32-bit, but overflow to the negative number range when interpreted as 32-bit signed integer. Therefore a is a negative Int and b is 0
i need to know the maximum value of float64 and complex128 variable types in golang. go doesn't seem to have an equivalent of float.h and i don't know how to calculate it.
For example,
package main
import (
"fmt"
"math"
)
func main() {
const f = math.MaxFloat64
fmt.Printf("%[1]T %[1]v\n", f)
const c = complex(math.MaxFloat64, math.MaxFloat64)
fmt.Printf("%[1]T %[1]v\n", c)
}
Output:
float64 1.7976931348623157e+308
complex128 (1.7976931348623157e+308+1.7976931348623157e+308i)
Package math
import "math"
Floating-point limit values. Max is the largest finite value
representable by the type. SmallestNonzero is the smallest positive,
non-zero value representable by the type.
const (
MaxFloat32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23
SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
MaxFloat64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
)
The Go Programming Language Specification
Numeric types
A numeric type represents sets of integer or floating-point values.
The predeclared architecture-independent numeric types are:
uint8 the set of all unsigned 8-bit integers (0 to 255)
uint16 the set of all unsigned 16-bit integers (0 to 65535)
uint32 the set of all unsigned 32-bit integers (0 to 4294967295)
uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615)
int8 the set of all signed 8-bit integers (-128 to 127)
int16 the set of all signed 16-bit integers (-32768 to 32767)
int32 the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
float32 the set of all IEEE-754 32-bit floating-point numbers
float64 the set of all IEEE-754 64-bit floating-point numbers
complex64 the set of all complex numbers with float32 real and imaginary parts
complex128 the set of all complex numbers with float64 real and imaginary parts
byte alias for uint8
rune alias for int32
The value of an n-bit integer is n bits wide and represented using
two's complement arithmetic.
There is also a set of predeclared numeric types with
implementation-specific sizes:
uint either 32 or 64 bits
int same size as uint
uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value
To avoid portability issues all numeric types are distinct except
byte, which is an alias for uint8, and rune, which is an alias for
int32. Conversions are required when different numeric types are mixed
in an expression or assignment. For instance, int32 and int are not
the same type even though they may have the same size on a particular
architecture.
You can also consider using the Inf method from the math package which
returns a value for infinity (positive or negative if you want), but is considered to be float64.
Not too sure if there is an argument for one or the other between math.MaxFloat64 and math.Inf(). Comparing the two I've found that Go interprets the infinity values to be larger than the max float ones.
package main
import (
"fmt"
"math"
)
func main() {
infPos := math.Inf(1) // gives positive infinity
fmt.Printf("%[1]T %[1]v\n", infPos)
infNeg := math.Inf(-1) // gives negative infinity
fmt.Printf("%[1]T %[1]v\n", infNeg)
}
Does anyone know why integer division in C# returns an integer and not a float?
What is the idea behind it? (Is it only a legacy of C/C++?)
In C#:
float x = 13 / 4;
//== operator is overridden here to use epsilon compare
if (x == 3.0)
print 'Hello world';
Result of this code would be:
'Hello world'
Strictly speaking, there is no such thing as integer division (division by definition is an operation which produces a rational number, integers are a very small subset of which.)
While it is common for new programmer to make this mistake of performing integer division when they actually meant to use floating point division, in actual practice integer division is a very common operation. If you are assuming that people rarely use it, and that every time you do division you'll always need to remember to cast to floating points, you are mistaken.
First off, integer division is quite a bit faster, so if you only need a whole number result, one would want to use the more efficient algorithm.
Secondly, there are a number of algorithms that use integer division, and if the result of division was always a floating point number you would be forced to round the result every time. One example off of the top of my head is changing the base of a number. Calculating each digit involves the integer division of a number along with the remainder, rather than the floating point division of the number.
Because of these (and other related) reasons, integer division results in an integer. If you want to get the floating point division of two integers you'll just need to remember to cast one to a double/float/decimal.
See C# specification. There are three types of division operators
Integer division
Floating-point division
Decimal division
In your case we have Integer division, with following rules applied:
The division rounds the result towards zero, and the absolute value of
the result is the largest possible integer that is less than the
absolute value of the quotient of the two operands. The result is zero
or positive when the two operands have the same sign and zero or
negative when the two operands have opposite signs.
I think the reason why C# use this type of division for integers (some languages return floating result) is hardware - integers division is faster and simpler.
Each data type is capable of overloading each operator. If both the numerator and the denominator are integers, the integer type will perform the division operation and it will return an integer type. If you want floating point division, you must cast one or more of the number to floating point types before dividing them. For instance:
int x = 13;
int y = 4;
float x = (float)y / (float)z;
or, if you are using literals:
float x = 13f / 4f;
Keep in mind, floating points are not precise. If you care about precision, use something like the decimal type, instead.
Since you don't use any suffix, the literals 13 and 4 are interpreted as integer:
Manual:
If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
Thus, since you declare 13 as integer, integer division will be performed:
Manual:
For an operation of the form x / y, binary operator overload resolution is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.
The predefined division operators are listed below. The operators all compute the quotient of x and y.
Integer division:
int operator /(int x, int y);
uint operator /(uint x, uint y);
long operator /(long x, long y);
ulong operator /(ulong x, ulong y);
And so rounding down occurs:
The division rounds the result towards zero, and the absolute value of the result is the largest possible integer that is less than the absolute value of the quotient of the two operands. The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs.
If you do the following:
int x = 13f / 4f;
You'll receive a compiler error, since a floating-point division (the / operator of 13f) results in a float, which cannot be cast to int implicitly.
If you want the division to be a floating-point division, you'll have to make the result a float:
float x = 13 / 4;
Notice that you'll still divide integers, which will implicitly be cast to float: the result will be 3.0. To explicitly declare the operands as float, using the f suffix (13f, 4f).
Might be useful:
double a = 5.0/2.0;
Console.WriteLine (a); // 2.5
double b = 5/2;
Console.WriteLine (b); // 2
int c = 5/2;
Console.WriteLine (c); // 2
double d = 5f/2f;
Console.WriteLine (d); // 2.5
It's just a basic operation.
Remember when you learned to divide. In the beginning we solved 9/6 = 1 with remainder 3.
9 / 6 == 1 //true
9 % 6 == 3 // true
The /-operator in combination with the %-operator are used to retrieve those values.
The result will always be of type that has the greater range of the numerator and the denominator. The exceptions are byte and short, which produce int (Int32).
var a = (byte)5 / (byte)2; // 2 (Int32)
var b = (short)5 / (byte)2; // 2 (Int32)
var c = 5 / 2; // 2 (Int32)
var d = 5 / 2U; // 2 (UInt32)
var e = 5L / 2U; // 2 (Int64)
var f = 5L / 2UL; // 2 (UInt64)
var g = 5F / 2UL; // 2.5 (Single/float)
var h = 5F / 2D; // 2.5 (Double)
var i = 5.0 / 2F; // 2.5 (Double)
var j = 5M / 2; // 2.5 (Decimal)
var k = 5M / 2F; // Not allowed
There is no implicit conversion between floating-point types and the decimal type, so division between them is not allowed. You have to explicitly cast and decide which one you want (Decimal has more precision and a smaller range compared to floating-point types).
As a little trick to know what you are obtaining you can use var, so the compiler will tell you the type to expect:
int a = 1;
int b = 2;
var result = a/b;
your compiler will tell you that result would be of type int here.