[英]Long Long Decimal Binary Representation using C
我一直在嘗試使用C編程打印長整型的二進制表示形式
我的代碼是
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation = binaryRepresentation + remainder * baseOfOne;
baseOfOne *= 10;
number = number / 2;
}
printf("%lld\n", binaryRepresentation);
}
當我提供5的輸入時,上面的代碼可以正常工作,而當數字為9223372036854775807 (0x7FFFFFFFFFFFFFFF)時,以上代碼將失敗。
1.測試用例
5
101
2.測試用例
9223372036854775807
-1024819115206086201
用一個拒絕數表示二進制數永遠不會特別好:輸入極少的數據,您很容易溢出,所有后續的算術運算將毫無意義。
另一種方法是隨手打印數字,但使用遞歸技術,以便以與處理數字相反的順序打印數字:
#include <stdio.h>
unsigned long long output(unsigned long long n)
{
unsigned long long m = n ? output(n / 2) : 0;
printf("%d", (int)(n % 2));
return m;
}
int main()
{
unsigned long long number = 9223372036854775807;
output(number);
printf("\n");
}
輸出:
0111111111111111111111111111111111111111111111111111111111111111
我也將類型更改為unsigned long long
,它具有更好定義的位模式, %
對於負數也會執行奇怪的操作。
確實,盡管如此,我在這里所做的只是濫用堆棧,以存儲實際上是一個零和一的數組的方式。
只是為了闡明一些注釋,最簡單的方法是使用char
數組保存二進制數字。 同樣,在處理位時,按位運算符會更清晰一些。 否則,我將保留您的基本代碼結構。
int main()
{
char bits[64];
int i = 0;
unsigned long long number; // note the "unsigned" type here which makes more sense
scanf("%lld", &number);
while (number > 0) {
bits[i++] = number & 1; // get the current bit
number >>= 1; // shift number right by 1 bit (divide by 2)
}
if ( i == 0 ) // The original number was 0!
printf("0");
for ( ; i > 0; i-- )
printf("%d", bits[i]); // or... putchar('0' + bits[i])
printf("\n");
}
正如Bathsheba的回答所言,如果使用十進制數字表示這樣的位序列,則需要的空間比可用空間更多。
由於您打算打印結果,因此最好一次打印一次。 我們可以通過創建僅設置最高位的掩碼來做到這一點。 為任何類型創建此功能的妙處在於對該類型的零進行補全以獲得“全1”數字。 然后,我們減去一半(即1111 ....-0111 ....),僅得到一位。 然后,我們可以沿數字向右移動它,依次確定每個位的狀態。
這是使用該邏輯的重新設計版本,並進行了以下其他更改:
printf
)打印的字符數。 #include <stdio.h>
#include <stdlib.h>
int print_binary(unsigned long long n)
{
int printed = 0;
/* ~ZERO - ~ZERO/2 is the value 1000... of ZERO's type */
for (unsigned long long mask = ~0ull - ~0ull/2; mask; mask /= 2) {
if (putc(n & mask ? '1' : '0', stdout) < 0)
return EOF;
else
++printed;
}
return printed;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
print_binary(strtoull(argv[i], 0, 10));
puts("");
}
}
讀者練習:
1
的布爾標志,要么在打印前有一個單獨的循環來移動掩碼)。 不要忘記檢查print_binary(0)
仍然產生輸出! strtoull
從十進制字符串轉換輸入值時檢查錯誤。 我不確定您真正想要實現什么,但是這里有一些代碼可以打印數字的二進制表示(將typedef
更改為所需的整數類型):
typedef int shift_t;
#define NBITS (sizeof(shift_t)*8)
void printnum(shift_t num, int nbits)
{
int k= (num&(1LL<<nbits))?1:0;
printf("%d",k);
if (nbits) printnum(num,nbits-1);
}
void test(void)
{
shift_t l;
l= -1;
printnum(l,NBITS-1);
printf("\n");
l= (1<<(NBITS-2));
printnum(l,NBITS-1);
printf("\n");
l= 5;
printnum(l,NBITS-1);
printf("\n");
}
如果您不介意分別打印數字,則可以使用以下方法:
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
void bindigit(long long num);
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
bindigit(number);
printf("\n");
}
void bindigit(long long num) {
int remainder;
if (num < 2LL) {
printf("%d",(int)num);
} else {
remainder = num % 2;
bindigit(num/2);
printf("%d",remainder);
}
}
最后,我自己嘗試了一個代碼,並從您的代碼中獲得了靈感,
#include<stdio.h>
#include<stdlib.h>
int main() {
unsigned long long number;
int binaryRepresentation[70], remainder, counter, count = 0;
scanf("%llu", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation[count++] = remainder;
number = number / 2;
}
for(counter = count-1; counter >= 0; counter--) {
printf("%d", binaryRepresentation[counter]);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.