Large Decimal Value to Binary in Arduino - arduino

I am trying to get the following decimal value
51043465443420856213 to binary in Arduino.
The result should be this.
10 1100 0100 0101 1110 1101 0001 0110 0001 1000 0100 0000 0110 1101 1111 1001 0101

Below is a code template to get you going as I did not want to give all the fun away.
void print_bin(char *s) {
// Keep track of carry from previous digit - what should this be initialized to?
int carry = ...;
// Divide the "number string" by 2, one digit/character at a time
// for each array element in `s` starting with the first character
for (... ; ... ; ...) {
// Extract the string element (character), covert to a decimal digit & add 10x carry
int digit = ...
// Divide digit by 2 and then save as a character
array element = ...
// Mod the digit by 2 as the new carry
carry = ...
}
// If first digit is a `0`, then move `s` to the next position.
if (*s == '0') {
...
}
// If `s` is not at the end, recursively call this routine on s
if (...) {
print_bin(s);
}
// Since the more significant digits have been printed, now print
// this digit (which is "mod 2" of the original "number string") as a character
fputc('0' + carry, stdout);
}
int main(void) {
char s[] = "51043465443420856213";
print_bin(s);
}
Result
101100010001011110110100010110000110000100000001101101111110010101

Apparently your value is not stored as a c program unsigned long long because it is bigger than 64 bits. Arduino has python. Here is a python function that does what you want. The example is using 80 bits. You can add spaces if you really want them.
def int2bin(n, count=24):
"""returns the binary of integer n, using count number of digits"""
return "".join([str((n >> y) & 1) for y in range(count-1, -1, -1)])
print int2bin(51043465443420856213, 80)
Output:
00000000000000101100010001011110110100010110000110000100000001101101111110010101

Related

Edit distance leetcode

So I am doing this question of EDIT DISTANCE and before going to DP approach I am trying to solve this question in recursive manner and I am facing some logical error, please help....
Here is my code -
class Solution {
public int minDistance(String word1, String word2) {
int n=word1.length();
int m=word2.length();
if(m<n)
return Solve(word1,word2,n,m);
else
return Solve(word2,word1,m,n);
}
private int Solve(String word1,String word2,int n,int m){
if(n==0||m==0)
return Math.abs(n-m);
if(word1.charAt(n-1)==word2.charAt(m-1))
return 0+Solve(word1,word2,n-1,m-1);
else{
//insert
int insert = 1+Solve(word1,word2,n-1,m);
//replace
int replace = 1+Solve(word1,word2,n-1,m-1);
//delete
int delete = 1+Solve(word1,word2,n-1,m);
int max1 = Math.min(insert,replace);
return Math.min(max1,delete);
}
}
}
here I am checking the last element of both the strings if both the characters are equal then simple moving both string to n-1 and m-1 resp.
Else
Now I am having 3 cases of insertion , deletion and replace ,and between these 3 I have to find minima.
If I am replacing the character then simply I moved the character to n-1 & m-1.
If I am inserting the character from my logic I think I should insert the character at the last of smaller length string and move the pointer to n-1 and m
To delete the element I think I should delete the element from the larger length String that's why I move pointer to n-1 and m but I think I am making mistake here please help.
Leetcode is giving me wrong answer for word1 = "plasma" and word2 = "altruism".
The problem is that the recursive expression for the insert-case is the same as for the delete-case.
Reasoning further, it turns out the one for the insert-case is wrong. In that case we choose to resolve the letter in word2 (at index m-1) through insertion, so it should not be considered any more during the recursive process. On the other hand the considered letter in word1 could still be matched with another letter in word2, so that letter should still be considered during the recursive process.
That means that m should be decremented, not n.
So change:
int insert = 1+Solve(word1,word2,n-1,m);
to:
int insert = 1+Solve(word1,word2,n,m-1);
...and it will work. Then remains to add the memoization for getting a good efficiency.
Python clean DP based solution,
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
return self.edit_distance(word1, word2)
#cache
def edit_distance(self, s, t):
# Edge conditions
if len(s) == 0:
return len(t)
if len(t) == 0:
return len(s)
# If 1st char matches
if s[0] == t[0]:
return self.edit_distance(s[1:], t[1:])
else:
return min(
1 + self.edit_distance(s[1:], t), # delete
1 + self.edit_distance(s, t[1:]), # insert
1 + self.edit_distance(s[1:], t[1:]) # replace
)

Why does this binary math fail when adding 00000001, but work correctly otherwise?

I've tried everything I can think of and cannot seem to get the below binary math logic to work. Not sure why this is failing but probably indicates my misunderstanding of binary math or C. The ultimate intent is to store large integers (unsigned long) directly to an 8-bit FRAM memory module as 4-byte words so that a micro-controller (Arduino) can recover the values after a power failure. Thus the unsigned long has to be assembled from its four byte words parts as it's pulled from memory, and the arithmetic of assembling these word bytes is not working correctly.
In the below snippet of code, the long value is defined as four bytes A, B, C, and D (simulating being pulled form four 8-bit memory blocks), which get translated to decimal notation to be used as an unsigned long in the arrangement DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAA. If A < 256 and B, C, D all == 0, the math works correctly. The math also works correctly for any values of B, C, and D if A == 0. But if B, C, or D > 0 and A == 1, the 1 value of A is not added during the arithmetic. A value of 2 works, but not a value of 1. Is there any reason for this? Or am I doing binary math wrong? Is this a known issue that needs a workaround?
// ---- FUNCTIONS
unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){
return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3)));
}
// ---- MAIN
void setup() {
Serial.begin(9600);
uint8_t addressAval = B00000001;
uint8_t addressBval = B00000001;
uint8_t addressCval = B00000001;
uint8_t addressDval = B00000001;
uint8_t addressValArray[4];
addressValArray[0] = addressAval;
addressValArray[1] = addressBval;
addressValArray[2] = addressCval;
addressValArray[3] = addressDval;
unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]);
// Print out resulting decimal value
Serial.println(decimalVal);
}
In the code above, the binary value should result as 00000001000000010000000100000001, AKA a decimal value of 16843009. But the code evaluates the decimal value to 16843008. Changing the value of addressAval to 00000000 also evaluates (correctly) to 16843008, and changing addressAval to 00000010 also correctly evaluates to 16843010.
I'm stumped.
The problem is that you're using pow(). This is causing everything to be calculated as a binary32, which doesn't have enough precision to hold 16843009.
>>> numpy.float32(16843009)
16843008.0
The fix is to use integers, specifically 65536 and 16777216UL.
Do not use pow() for this.
The usual way to do this is with the shift operator:
uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);

Twos complement on hex

Given:
int number = 0xFFFFFF87;
number = ~number + 1;
printf ("%x", number);
Why does 'number' become '79' instead of '87'? How can i make it '87' ?
It is 0x79 because ~0xFFFFFF87 = 0x00000078 and when 1 is added you get 0x00000079.
To get 0x87, you should use:
int number = 0xFFFFFF87 & 0xFF;
which will select only the least significant byte and mask the other bytes with zero.
~ negates every bit, not only the ones with hex group of 0xF.
To make it 0x87 just reverse the operation, i.e.:
int number = ~(0x87-1); // which is 0xFFFFFF79

About pointers and ASCII code

im learning more about c language and i have 1 doubt about 1 code that i have seen.
main(){
int i = (65*256+66)*256+67;
int* pi;
char* pc;
pi = &i;
pc = (char*)pi;
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
}
Output is: C B A
I know that ASCII code of A is 65, B is 66, and C is 67 but the variable i is none of them.
If i put variable i=65, the output is just A and dont show B or C, why?
And i would like to know why this code have that output. Thanks for any help.
The line
int i = (65*256+66)*256+67;
turns i into the following
00000000 01000001 01000010 01000011
int = 4 bytes or 4 groups of 8 bits
char = 1 byte or 1 group of 8 bits.
What happens is that a char pointer is used to point to a subset of the original int bits.
At first the pointer points to the 8 least significant bits (the group to the right).
And the letter C is printed. Then, the pointer it self is incremented by 1 which makes it point to the next group of 8 bits in the memory which happens to be B. And once more for the A.
*256 means left shift by 8 bit (1 byte) so the line
int i = (65*256+66)*256+67;
actually put A,B,C on 3 adjacent bytes in memory
then pi pointer made point to the address of integer i, then same address down cast to char pointer pc, so pc actually hold the address to a byte that contains 'A', and of course if you add 1 and 2 to the address that means the adjacent 'B' and 'C' get pointed to and print out.
EDIT: just to clarify a bit more int is 32 bit long but char is 8 bit, that's why u need a char pointer to represent an address valid for 8 bit long.
Characters are stored as bytes, as you probably know. The initializing of the variable 'i' has the following meaning:
65*256 // store 65 ('A') and left shift it by 8 byte (= '*256')
(65*256+66)*256 // add 66 ('B') and shift the whole thing again
(65*256+66)*256+67 // add 67 ('C')
'pi' is initialized as a INT pointer to 'i'
'pc' is initialized as a CHAR pointer to 'pi'
So 'pc' then holds the address of the beginning of the 3 bytes stored in 'i', which holds 'A'.
By adding 1 and 2 to the address in pc, you get the second and third bytes (containing 'B' and 'C'), as follows:
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
Working on the bits here ;D

Math: removing a digit from a number

Let's say that I have the following number: 1286 now I want to remove the last digit 6 and end up with the first 3 digits 128 only. I also would like to do this using the number 6 and the number 1286 only as inputs.
Also if there is a c# solution would be great.
Thanks
Edit:
I want to do this using a math equation between the 6 and the 1286, I already know how to parse strings, which is not what I'm after.
please try the below code: (this is done only using mathematical functions, also I don't know C#)
java.util.Scanner s=new java.util.Scanner(System.in);
int last=s.nextInt();
int firstNumber=s.nextInt();
int ans=0;
loop:
for(int temp=firstNumber,i=0;temp>0;temp/=10)
{
if(temp%10==last){ans=temp/10;while(i>0){ans=ans*10+(i%10);i/=10;} break loop;}
i=i*10;
i=i+(temp%10);
}
if(ans>0)System.out.println(ans);
}
}
string input = "OneTwoThree";
// Get first three characters
string sub = input.Substring(0, 3);
sub will now have the first 3 chars from the string, the 0 is the start pos, and then how many chars do you want (ie: 3) - this is where the (0, 3) come in to it - if you had (3, 3), sub would equal "Two"
I think this might be what you are looking for :)
In JavaScript: Here is your number:
var num = 1286;
This line removes the last digit:
num % 10; //returns 6
And these two lines remove the 6:
num /= 10 // turns num to 128.6
num = Math.trunc(num) // num now equals 128
Better yet, you could put it in a function, like so:
function sumOfDigits(num) {
const sumArr = [];
while (num > 0) {
sumArr.push(num % 10);
num /= 10;
num = Math.trunc(num);
}
return sumArr.reduce((a, b) => a + b, 0);
}
sumOfDigits(1234);
// returns 10
Hope this helps.

Resources