Answer the question
In order to leave comments, you need to log in
How to write very fast (let platform-specific) abs(x int32) in Go?
I am writing a number crusher. The speed of the operation is critical. abs() for int32 is not implemented in stdlib. This does not work (well, or there is not enough ability to implement it).
uint32(x) works, but what is there in general is not intuitive.
unsafe.Pointer() is taken so what? https://play.golang.org/p/ZAAJTv3sA_
On irc #go-nuts they said that the sign is exactly in the upper bit. Tell me how to get to it bitwise.
If without inventions to write
if x<0 {x=-x}; //and this is a shift check and two copies
, will the compiler just mask the sign without checks? For float64 in stdlib.math, this is actually done, but ...
The task is private - int32, GOOS/ARCH=linux/amd64
Answer the question
In order to leave comments, you need to log in
here is the implementation on go https://play.golang.org/p/zTe6pRwx0Y (based on "it doesn't work")
package main
import "fmt"
func abs(x int) int {
m := x >> 31
return (x + m) ^ m
}
func main() {
fmt.Println(abs(-65580))
}
01 MOVQ $-65580,AX
02 MOVQ AX,DX
03 SARQ $31,AX
04 ADDQ AX,DX
05 XORQ AX,DX
int32 is a fixed word length, bits are "numbered" without regard to endianness - it's hard to "miss" (:)) even on a different architecture. We overwrite the most significant bit (actually the sign) and voila. ... And the examples given by you (uvelichitel) are working, as neolink has already shown.
So it’s true, but the code of negative numbers is additional up to 2-x ... therefore we select the highest bit with a mask and cunningly dance with a tambourine also because there is no bitwise negation in go (!)
but in general you need
To get the number itself from the additional code... .
#include <stdlib.h>
#include <unistd.h>
int i32abs4training(int x)
{
int m;
m = 2*((x >> 31)&1) - 1; // negative or positive (invers)
// printf("bits in a integer word %i\n", sizeof(x)*8);
return ~(m*x) + 1;
}
int main()
{
printf ("%i\n", i32abs4training(-12));
printf ("%i\n", i32abs4training(12));
printf ("%i\n", i32abs4training(14));
printf ("%i\n", i32abs4training(-32768));
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question