Merge two ASCII DEC values together and convert to int - arduino

i have two DEC variables and i would like to merge them like this:
unsigned int first_dig = 57; // Number 9
unsigned int second_dig = 52; // Number 4
unsigned int all_dig = 0;
Now i want to save them in all_dig. I already tried to shift bytes but it ends up in a Mess
all_dig = ((first_dig<<8)|second_dig); // prints 14644
I want all_dig to contain 94. Is there a simpler way? I would like to use the same concept for three digits too.
Thanks already for the help

For two digits, d_1, d_0:
res = (d_1 - '0') * 10 + (d_0 - '0')
For three digits, d_2, d_1, d_0:
res = (d_2 - '0') * 100 + (d_1 - '0') * 10 + (d_0 - '0')
Notice that the expression is only valid if
'0' <= d_i <= '9' for each d_i
If that were not the case, the result wouldn't be correct.

Related

Limit a value between min and max using only arithmetic

Is it possible to limit a value in a given range, between min and max, using only arithmetic? That is, + - x / and %?
I am not able to use functions such as min, max nor IF-statements.
Let's assume I have a range of [1850, 1880], for any values < 1850, it should display 1850. For values > 1880, 1880 should be displayed. It would also be acceptable if only 1850 was displayed outside the range.
I tried:
x = (((x - xmax) % (xmax - xmin)) + (xmax - xmin)) % (xmax - xmin) + xmin
but it gives different values in the middle of the range for values lower than xmin.
If you know the size of the integer type, you can extract its sign bit (assuming two's complement) using integer division:
// Example in C
int sign_bit(int s)
{
// cast to unsigned (important)
unsigned u = (unsigned)s;
// number of bits in int
// if your integer size is fixed, this is just a constant
static const unsigned b = sizeof(int) * 8;
// pow(2, b - 1)
// again, a constant which can be pre-computed
static const unsigned p = 1 << (b - 1);
// use integer division to get top bit
return (int)(u / p);
}
This returns 1 if s < 0 and 0 otherwise; it can be used to calculate the absolute value:
int abs_arith(int v)
{
// sign bit
int b = sign_bit(v);
// actual sign (+1 / -1)
int s = 1 - 2 * b;
// sign(v) * v = abs(v)
return s * v;
}
The desired function looks like this:
It is useful to first shift the minimum to zero:
This function form can be computed as a sum of the two shifted absolute value functions below:
However the resultant function is scaled by a factor of 2; shifting to zero helps here because we only need to divide by 2, and shift back to the original minimum:
// Example in C
int clamp_minmax(int val, int min, int max)
{
// range length
int range = max - min;
// shift minimum to zero
val = val - min;
// blue function
int blue = abs_arith(val);
// green function
int green = range - abs_arith(val - range);
// add and divide by 2
val = (blue + green) / 2;
// shift to original minimum
return val + min;
}
This solution, although satisfies the requirements of the problem, is limited to signed integer types (and languages which allow integer overflow - I'm unsure of how this could be overcome in e.g. Java).
I found this while messing around in... excel. It only works for strictly positive integers. Although this is not more restrictive as the answer by meowgoesthedog because he also effectivly halves the integer space by dividing by two at the end. It doesn't use mod.
//A = 1 if x <= min
//A = 0 if x >= min
A = 1-(min-min/x)/min
//B = 0 if x <= max
//B = 1 if x > max
B = (max-max/x)/max
x = A*min + (1-A)*(1-B)*x + B*max
I found this solution in Python:
A = -1 # Minimum value
B = +1 # Maximum value
x = min(max(x, A), B)

Is it possible to decode a SPAMCAUSE field in a mail header?

I'd like to decode this string:
X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelgedrvdduucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenucgohfhorhgsihguuggvnhfjughrucdlhedttddm
How can I do this?
There is a Tor hidden service you can use to decode the tag located at http://6jbnmws2zq2m2fsfmpwnssgsrxovohgggphymkd4df2pgcw7ccrdy6ad.onion
According to it, the X-OVH-SPAMCAUSE you gave translates to this:
Vade Retro 01.394.21 AS+AV+AP+RT Profile: OVH; Bailout: 300; ^ForbiddenHdr (500)
Starting from lkraider's great Python answer, I improved the accuracy. It turns out that the offset characters (c..g) are alternately appended and prepended. So instead of just checking if one of them is in the pair, it is necessary to differentiate between, e.g., fh and hf, by keeping track of even or odd pairs.
def decode(msg):
text = ""
for i in range(0, len(msg), 2):
# add position as extra parameter
text += unrot(msg[i: i + 2], i // 2)
return text
def unrot(pair, pos, key=ord('x')):
# "even" position => 2nd char is offset
if pos % 2 == 0:
# swap letters in pair
pair = pair[1] + pair[0]
# treat 1st char as offset
offset = (ord('g') - ord(pair[0])) * 16
# map to original character
return chr(sum(ord(c) for c in pair) - key - offset)
print(decode('gggruggvucftvghtrhho'))
https://gist.github.com/DoubleYouEl/e3de97293ce3d5452b3be7a336a06ad7
Looks to be some obfuscation by rotating chars. I made an attempt at it using Python. It's not perfect but mostly seems to work:
def decode(msg):
text = []
for i in range(0, len(msg), 2):
text.append(unrot(msg[i: i + 2]))
return str.join('', text)
def unrot(pair, key=ord('x')):
offset = 0
for c in 'cdefgh':
if c in pair:
offset = (ord('g') - ord(c)) * 16
break
return chr(sum(ord(c) for c in pair) - key - offset)
print(decode('gggruggvucftvghtrhho'))
https://gist.github.com/lkraider/9530798a695586fc1580d0728966f6f0
I improved the given Python solutions by Ikraider and DoubleYou and added a JavaScript solution, too.
Python:
def Decode(msg):
return ''.join([chr(ord(msg[i * 2]) + ord(msg[i * 2 + 1]) - 1768 + ord(msg[i * 2 + 1 - (i & 1)]) * 16) for i in range(len(msg) // 2)])
print(Decode('gggruggvucftvghtrhho'))
JavaScript:
function Decode(msg)
{
return Array(msg.length >> 1).fill(0).map((_, i) => String.fromCharCode(msg[i * 2].charCodeAt(0) + msg[i * 2 + 1].charCodeAt(0) - 1768 + (msg[i * 2 + 1 - (i & 1)].charCodeAt(0) << 4))).join('');
}
console.log(Decode('gggruggvucftvghtrhho'));

How to get the last digit of a number without using modulus(%) operator?

If we are told that we can't use modulus operator then how can we take
out the last digit of a number.
e.g.
N=2345, we should get 5.
Try to provide a generic solution.
What I found:
N- N/ 10 * 10
The formula you provided will work.
Generally speaking, for Integers >= 0 this will always be true
A % B = A - [A/B] * B, where [x] denotes greatest integer <= x
http://jsfiddle.net/e51mg205/
number = 2345;
arr = (""+number).split('');
console.log(arr[arr.length-1])
By casting.
but this require some checks before.
simple example:
int num = 15;
double d = num/10; //d = 1.5
num = num/10; //num = 1;
int lastNumber = (d - (double)num) * 10;

Arduino: Formula to convert byte

Im looking for a way to modify a binary byte value on Arduino.
Because of the Hardware, its neccesarry, to split a two digit number into 2 4-bit.
the code to set output is wire.write(byte, 0xFF) which sets all outputs on High.
0xFF = binary 1111 1111
the formula should be convert a value like this:
e.g nr 35 is binary 0010 0011
but for my use it should displayed as 0011 0101 which would be refer to 53 in reality.
The first 4 bits are for a BCD-Input IC which displays the 5 from 35, the second 4 bits are for a BCD-Input IC which displays the 3 from 35.
Does anybody has a idea how to convert this by code, or like a mathematical formula?
Possible numbers are from 00 to 59.
Thank you for your help
To convert a value n between 0 and 99 to BCD:
((n / 10) * 16) + (n % 10)
assuming n is an integer and thus / is doing integer division; also assumes this will be stored in an unsigned byte.
(If this is not producing the desired result, please either explain how it is incorrect for the example given, or provide a different example for which it is incorrect.)
#include <string.h>
int num = // Any number from 0 to 59
int tens = num/10;
int units = num-(tens*10);
// Make string array for binary
string tensbinary;
int quotient = tens;
char buffer[1];
// Convert numbers
for (int i = 0; i < 4; i++)
{
quotientint = quotientint % 2;
sprintf(buffer, 1, "%d", quotientint);
binary.append(buffer);
}
// Repeat above for the units
// Now join the two together
binarytens.append(binaryunits);
I don't know if this will work, but still, you might be able to extrapolate based on the available information in my code.
The last thing you need to do is convert the string to binary.

How to divide an odd number to leave two integers?

If I have an odd number, how would I divide it in two and leave two integers, with the first being one more than the second. For instance 9 would produce 5 and 4?
The "smaller half" of int x is x/2. The "bigger half" is x/2 + x%2 or x - x/2.
Note that "smaller" and "bigger" refer to the absolute value, so in the case of negative x, bigger < smaller.
Of course, if x is always odd and positive, then x%2 will be 1 and the bigger half can also be computed as x/2 + 1.
What about this?
int a = 9;
int c = a/2;
int b = a-c;
This would be my recommended way:
int low = floor(x / 2.0f);
int high = ceil(x / 2.0f);
I find it to be more concise than the x/2 + x%2 version.
This version also benefits from the fact that the output will be correct if you happen to run it using an even number.
EDIT:
People seemed to complain about me using floating point for integers, well here is a completely bitwise based version:
int a = 9;
int b = a >> 1;
int c = b | (a & 0x1);
The only caveat with #2 is that if the input is negative, the results will not be what is expected.
For the folks who use microcontrollers, where / and % are fearsome-cost operations :-)
This shows an alternative method, using shift >> and & which are sometimes cheaper:
#include <stdio.h>
int main (int argc, const char * argv[]) {
const int iplus = 9;
const int iminus = -9;
printf("iplus=%d iminus=%d\n", iplus, iminus);
printf("(iplus >> 1)=%d ((iplus >> 1) + (iplus & 1))=%d\n", iplus >> 1, (iplus >> 1) + (iplus & 1));
printf("(iminus >> 1)=%d ((iminus >> 1) + (iminus & 1))=%d\n", iminus >> 1, (iminus >> 1) + (iminus & 1));
return 0;
}
Output:
iplus=9 iminus=-9
(iplus >> 1)=4 ((iplus >> 1) + (iplus & 1))=5
(iminus >> 1)=-5 ((iminus >> 1) + (iminus & 1))=-4
According to this Does either ANSI C or ISO C specify what -5 % 10 should be?
There is a difference of behaviour for / between C89 and C99, and specifically C89 '/ with one negative number may return a positive or negative result, but C99 is negative.
I thought the accepted answer was in the ballpark but unclear. If you want some copy and paste code this would be the best solution in my eyes
var number = 11;
var halfRoundedUp = (number % 2) ? number/2 + .5 : number/2;
var halfRoundedDown = (number % 2) ? number/2 - .5 : number/2;
alert(halfRoundedUp +" "+ halfRoundedDown);

Resources