Конвертировать Binary в Integer
- Войдите на сайт для отправки комментариев
Втр, 20/01/2015 - 23:51
есть строка String s1 = "111110010101";
и хочу чтобы получился результат int i = 3989;
Подскажите как реализовать?
есть строка String s1 = "111110010101";
и хочу чтобы получился результат int i = 3989;
Подскажите как реализовать?
построить цикл по сканированию строки по одному символу слева направо. перед циклом объявить переменную int присвоив ей 0. на каждой итерации цикла выставляем нулевой бит исходя из того есть единица в сканированном символе или нет и сдвигаем число влево
int i = 0; for( int Pos = 0; s1[Pos] != 0; Pos++ ) { i = ( i << 1 ) | ( s1[Pos] - '0' ); }Так, что ли, получается? :)
Долго мучился и в итоге получилось вот так:
int BinToInt(String st) { int i, stLen; int Result = 0; stLen = st.length(); for (int a = stLen; a > 0 ; a-- ) { if (st[a-1] == '1') { i = 1 << ((stLen-1)-(a-1)); Result = Result + i; } } return Result; }Я думаю, где то так:
unsigned long conv(char *str) { unsigned long l1=0; while(*str) l1 = (l1 << 1) | (unsigned long) (*str++ - 48); return l1; }unsigned long - 8 байта , long - 4 байта , ...................
BIN 110110010110001010110111 >>> HEX D962B7 ( ЭТО 6 БАЙТ ) >>> DEC 14246583
выделенное откусит разрядная сетка представления чисел, и останется вот так
BIN 0110001010110111 >>> HEX 62B7 ( ЭТО 4 БАЙТа ) >>> DEC 25271
всё правильно МК сделал :)
чёта покурепалось всё....
Долго мучился и в итоге получилось вот так:
int BinToInt(String st) { int i, stLen; int Result = 0; stLen = st.length(); for (int a = stLen; a > 0 ; a-- ) { if (st[a-1] == '1') { i = 1 << ((stLen-1)-(a-1)); Result = Result + i; } } return Result; }#1 - unsigned long
#2 - unsigned long и byte
#3 -unsigned long
#5 - byte
Долго мучился и в итоге получилось вот так:
int BinToInt(String st) { int i, stLen; int Result = 0; stLen = st.length(); for (int a = stLen; a > 0 ; a-- ) { if (st[a-1] == '1') { i = 1 << ((stLen-1)-(a-1)); Result = Result + i; } } return Result; }#1 - unsigned long
#2 - unsigned long и byte
#3 -unsigned long
#5 - byte
unsigned long BinToInt(String st) { byte stLen; unsigned long i,Result = 0; stLen = st.length(); for (byte a = stLen; a >0 ; a-- ) { if (st[a-1] == '1') { i = 1 << ((stLen-1)-(a-1)); Serial.println(i); Result = Result + i; } } return Result; }Результат остался прежний..
Долго мучился и в итоге получилось вот так:
int BinToInt(String st) { int i, stLen; int Result = 0; stLen = st.length(); for (int a = stLen; a > 0 ; a-- ) { if (st[a-1] == '1') { i = 1 << ((stLen-1)-(a-1)); Result = Result + i; } } return Result; }я думал ЭТО работает... вот и допеределал :(
Если не работает всегда можно сделать как в школе на бумажке делали :) Оно всегда работает.
unsigned long BinToInt(String st) { byte stLen; unsigned long i,Result = 0; stLen = st.length(); for (byte a = 0; a < stLen; a++) { if (st[a] == '1') { Result += mypow(2, (stLen-1-a)); } } return Result; } unsigned long mypow(byte base, byte exponent) { unsigned long Result = 1; for(byte i=1;i<=exponent;i++) Result *= base; return Result; }Стандартная pow() точность не даёт, поэтому её использовать не получится, результат будет неточным.
Другое дело если надо красивый локаничный код :)
http://bigbarrel.ru/convert_string_binary_to_byte/
Другое дело если надо красивый локаничный код :)
а если надо для слома мозгов ? поможете ?
задумка такая - адрес строки как массива известен, длину строки - через sizeof() , в массив на 4 байта ( 8 байтов ) запихнуть эту строку, выравнивая по правому краю ( 0=х30=b0011000 , 1=х31=b0011001 - нулевой бит символа 0 или 1 писать в байт и двигать его ) ,
а потом интерпретировать этот массив как int (
unsignedlong )...ну, и ещё вопрос - как float распихана по 8-ми байтам в ардуине ? Число в формате ПТ или ЧФПТнормализованное ? Или ардуина знакома со стандартом на числа ПТ ANSI/IEEE 754-1985 - Short Real ?
Очень хочется распотрошить , например , 165.762545 - что да как там по байтам....
Спасибо :)
через так
union CharInt { char ar[ 9 ]; int n; };
возможный путь решения ?
Если не работает всегда можно сделать как в школе на бумажке делали :) Оно всегда работает.
unsigned long BinToInt(String st) { byte stLen; unsigned long i,Result = 0; stLen = st.length(); for (byte a = 0; a < stLen; a++) { if (st[a] == '1') { Result += mypow(2, (stLen-1-a)); } } return Result; } unsigned long mypow(byte base, byte exponent) { unsigned long Result = 1; for(byte i=1;i<=exponent;i++) Result *= base; return Result; }Стандартная pow() точность не даёт, поэтому её использовать не получится, результат будет неточным.
Другое дело если надо красивый локаничный код :)
Сидел, думал, исправлял и получилось подлиннее, но только так)
unsigned long BinToInt(String st) { byte stLen; unsigned long i,Result = 0; stLen = st.length(); for (byte a = stLen; a >0 ; a-- ) { if (st[a-1] == '1') { i = shl((stLen-1)-(a-1)); Result = Result + i; } } return Result; } unsigned long shl(byte by) { unsigned long p; if (by == 0) p = 1; else if (by == 1) p = 2; else { p = pow(2,by); if (p%2 != 0) p = p + 1; if (by == 20) p = 1048576; if (by == 22) p = 4194304; if (by == 23) p = 8388608; if (by == 24) p = 16777216; } return p; }Единственное что не понял, это почему pow() работает так непонятно..
Ну тут я Вам не помогу, давно это всё было и неправда :) Помню как я не любил когда нам давали числа с плавающей точкой, а нам надо было на листике представить их так как они лежат в памяти ЭВМ :) Я с ардуино по работе не связан, так для себя мелочи всякие делаю. А коллега на работе (который ардуино заведует) говорит, что float вообще не использует, вместо них хранит в лонгах мантису экспоненты и собирает всё как ему надо, говорит быстро и самое главное точно.
Видел на arduino.cc выкладывали функции IEEE754 для работы с 32 и 64 бита
Единственное что не понял, это почему pow() работает так непонятно..
она оперирует float а у него точность 6-7 знаков, если, например, написать pow(2, 23) получите не тоже самое что на калькуляторе
...... А коллега на работе (который ардуино заведует) говорит, что float вообще не использует, вместо них хранит в лонгах мантису экспоненты и собирает всё как ему надо, говорит быстро и самое главное точно.
Видел на arduino.cc выкладывали функции IEEE754 для работы с 32 и 64 бита
тоже хотел бы поиграть с точностью :) , спасибо !
от sva1509 - 2674 bytes / 25 mSec
char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> out = conv( str1 ); //>> } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Serial.println( millis() - T ); Serial.println( out ); delay( 500 ); } //===================================== unsigned long conv( char *str ) { unsigned long l1 = 0; // while( *str ) l1 = ( l1 << 1 ) | ( unsigned long ) ( *str++ - 48 ); while( *str ) l1 = ( l1 << 1 ) | ( *str++ - 48 ); return l1; } //=====================================у миня получилось только так :( - 2696 bytes / 30 mSec
char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; union CharInt { unsigned long intN; char strN[ 33 ]; }; CharInt abc = { 0x0000000000000000 }; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> out = binToLong( str1 ); //>> } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Serial.println( millis() - T ); Serial.println( out ); delay( 500 ); } //===================================== unsigned long binToLong( char *str ) { int i = 0; while ( str1[ i ] != NULL ) { abc.intN <<= 1; abc.strN[ 0 ] = abc.strN[ 0 ] | ( str1[ i ] & 0x01 ); i++; } return abc.intN; } //===================================== /* unsigned long binToLong( char *str ) { char *strTemp; strTemp = & abc.strN[ 0 ]; while ( *str != NULL ) { abc.intN <<= 1; *strTemp = *strTemp | ( *str++ & 0x01 ); } return abc.intN; } */ //=====================================Доброго времени суток !
а попробуйте еще так :
char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> //out = conv( str1 ); //>> while( *str ) out = ( out << 1 ) | ( *str++ - 48 ); } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Serial.println( millis() - T ); Serial.println( out ); delay( 500 ); }просто интересно что получится.
сначала понять надо :)
ваша конвертация все равно занимает одну строку, я вам просто заменил строку вызова функции на строку конвертации, что по идее должно ускорить процесс. К стати я допустил ошибку предварительно не обнулив out.
char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; char *str; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> // out = conv( str1 ); //>> out = 0; str = & str1; while( *str ) out = ( out << 1 ) | ( *str++ - 48 ); } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; char *str; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> // out = conv( str1 ); //>> out = 0; str = & str1; while( *str ) out = ( out << 1 ) | ( *str++ - 48 ); } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ага, исправил... и указатель не обьявили, только как его разыменовать или как там это называется :)
char str1[ 33 ] = "11111111111111111111111111111111"; unsigned long out; //char *str = str1; char *str; //===================================== void setup() { Serial.begin( 9600 ); } //===================================== void loop() { unsigned long T = millis(); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ( int i = 0; i < 500; i++ ) //>> { //>> // out = conv( str1 ); //>> // char *str = str1; // *str = &str1; str = str1; out = 0; while( *str ) out = ( out << 1 ) | ( *str++ - 48 ); } //>> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>если объявить и инициировать в строке 3 - не работает
если объявить и инициировать в строке 18 - работает , время тоже 25 mSec
если объявить в строке 4 , а и инициировать в лупе str = str1; - работает , но время 50 mSec
если объявить в строке 4 , а и инициировать в лупе str = &str1; - ругается
если объявить в строке 4 , а и инициировать в лупе *str = str1; - ругается
если объявить в строке 4 , а и инициировать в лупе *str = &str1; - ругается
все варианты преберал - но в книжке же пишут, что надо char *str = &str1;
почему не работает с амперсандом ?
как правильно объвить в секции определений, а инициировать в лупе ?
если char *str = str1; в верхней секции и char *str = str1; в лупе - это же два указателя ?
один глобальный, второй - локальный для лупа ?
спасибо ! :)
правильно объявлять str = str1; дело в том что имя массива это тоже указатель. Когда вы указываете &str1 это уже адрес адреса. Когда указываете *str это вы обращаетесь к данным по адресу str.