Most languages are like stackoverflow: I have a question, I want the best answer.
Perl is like PerlMonks: I have a doubt, I want to read an interesting discussion about it that is likely to go on a tangent. q-:
-- tye in Re: What is PerlMonks? (why Perl)
Poor old bartender1382 asking the simple and naive question "How can I set a bit to 0?"
seems to have got more than he bargained for. Thanks Grumpy Gramps! :)
For cheap thrills, let's try to steer this thread further off course with a couple of example programs
to add numbers using only bitwise operators.
Improvements, alternative implementations welcome.
Note: this was just for fun, I've never had a genuine need to do this, interested to hear from folks who have.
Perl Program to Add Two Numbers Using Only Bitwise Operators
# Perl program to add two numbers using only bitwise operators
# See https://stackoverflow.com/questions/4068033/add-two-integers-usi
+ng-only-bitwise-operators
use strict;
use warnings;
# See [id://11135535] (note that <C>use integer</C> subtly affects bit
+ operations in Perl)
use integer;
sub BitAdd1 {
my ($aa, $bb) = @_;
my $carry = $aa & $bb;
my $result = $aa ^ $bb;
while ($carry != 0) {
my $s_carry = $carry << 1;
$carry = $result & $s_carry;
$result ^= $s_carry;
}
return $result;
}
sub BitAdd2 {
my ($aa, $bb) = @_;
$bb == 0 and return $aa;
return BitAdd2($aa ^ $bb, ($aa & $bb) << 1);
}
for my $r ( [0, 1],
[1, -1],
[69, -42],
[42, 69],
[-42, 69],
[-42, -69],
[256, 512],
[123456789, 1],
[2147483647, 1],
[-2147483648, 1] ) {
my $sum0 = $r->[0] + $r->[1];
my $sum1 = BitAdd1($r->[0], $r->[1]);
my $sum2 = BitAdd2($r->[0], $r->[1]);
print "$r->[0] + $r->[1] = $sum0 ($sum1 $sum2)\n";
$sum0 == $sum1 or die "oops 1";
$sum0 == $sum2 or die "oops 2";
$sum1 == $sum2 or die "oops 3";
}
Example run:
0 + 1 = 1 (1 1)
1 + -1 = 0 (0 0)
69 + -42 = 27 (27 27)
42 + 69 = 111 (111 111)
-42 + 69 = 27 (27 27)
-42 + -69 = -111 (-111 -111)
256 + 512 = 768 (768 768)
123456789 + 1 = 123456790 (123456790 123456790)
2147483647 + 1 = 2147483648 (2147483648 2147483648)
-2147483648 + 1 = -2147483647 (-2147483647 -2147483647)
C++ Program to Add Two Numbers Using Only Bitwise Operators
// C++ Program to add two numbers without using arithmetic operator.
// bitadd.cpp
// Built with : g++ -o bitadd -std=c++11 -Wall -O3 bitadd.cpp
#include <cstddef>
#include <cstdint>
#include <vector>
#include <utility>
#include <iostream>
#include <fstream>
#include <sstream>
// uncomment one of these
// typedef int32_t my_int;
typedef int64_t my_int;
my_int Add(my_int x, my_int y)
{
// Iterate till there is no carry
while (y != 0) {
// carry now contains common set bits of x and y
my_int carry = x & y;
// Sum of bits of x and y where at least one of the bits is no
+t set
x = x ^ y;
// Carry is shifted by one so that adding it to x gives requir
+ed sum
y = carry << 1;
}
return x;
}
using my_list_type = std::vector< std::pair<my_int, my_int> >;
int main()
{
my_list_type ops = {
{ 0, 1 },
{ 1, -1 },
{ 69, -42 },
{ 42, 69 },
{ -42, 69 },
{ -42, -69 },
{ 256, 512 },
{ 123456789, 1 },
{ 2147483647, 1 },
{ -2147483648, 1 }
};
my_int sum0, sum1;
std::cout << "sizeof my int = " << sizeof(my_int) << "\n";
for (const auto& c : ops) {
sum0 = c.first + c.second;
sum1 = Add(c.first, c.second);
if (sum0 != sum1) { std::cout << "oops!\n"; }
std::cout << c.first << " + " << c.second << " = " << sum0 << "
+(" << sum1 << ")\n";
}
return 0;
}
Example run:
sizeof my int = 8
0 + 1 = 1 (1)
1 + -1 = 0 (0)
69 + -42 = 27 (27)
42 + 69 = 111 (111)
-42 + 69 = 27 (27)
-42 + -69 = -111 (-111)
256 + 512 = 768 (768)
123456789 + 1 = 123456790 (123456790)
2147483647 + 1 = 2147483648 (2147483648)
-2147483648 + 1 = -2147483647 (-2147483647)
See Also
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.