我目前正在研究一个将二进制数转换为八进制数的基本程序。它的任务是打印一个表,其中所有数字都在0-256之间,其二进制,八进制和十六进制等效。该任务要求我只使用自己的代码(即使用循环等而不是内置函数)。我所制作的代码(目前非常混乱)如下(这只是一个snippit):
int counter = ceil(log10(fabs(binaryValue)+1));
int iter;
if (counter%3 == 0)
{
iter = counter/3;
}
else if (counter%3 != 0)
{
iter = ceil((counter/3));
}
c = binaryValue;
for (int h = 0; h < iter; h++)
{
tempOctal = c%1000;
c /= 1000;
int count = ceil(log10(fabs(tempOctal)+1));
for (int counter = 0; counter < count; counter++)
{
if (tempOctal%10 != 0)
{
e = pow(2.0, counter);
tempDecimal += e;
}
tempOctal /= 10;
}
octalValue += (tempDecimal * pow(10.0, h));
}
输出完全错误。例如,当二进制代码是1111(十进制值15)时,它输出7.我可以理解为什么会发生这种情况(二进制数中的最后三位数,111,十进制格式为7),但不能识别代码中的问题。有什么想法吗?
编辑:经过一些调试和测试后,我找到了答案。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
while (true)
{
int binaryValue, c, tempOctal, tempDecimal, octalValue = 0, e;
cout << "Enter a binary number to convert to octal: ";
cin >> binaryValue;
int counter = ceil(log10(binaryValue+1));
cout << "Counter " << counter << endl;
int iter;
if (counter%3 == 0)
{
iter = counter/3;
}
else if (counter%3 != 0)
{
iter = (counter/3)+1;
}
cout << "Iterations " << iter << endl;
c = binaryValue;
cout << "C " << c << endl;
for (int h = 0; h < iter; h++)
{
tempOctal = c%1000;
cout << "3 digit binary part " << tempOctal << endl;
int count = ceil(log10(tempOctal+1));
cout << "Digits " << count << endl;
tempDecimal = 0;
for (int counterr = 0; counterr < count; counterr++)
{
if (tempOctal%10 != 0)
{
e = pow(2.0, counterr);
tempDecimal += e;
cout << "Temp Decimal value 0-7 " << tempDecimal << endl;
}
tempOctal /= 10;
}
octalValue += (tempDecimal * pow(10.0, h));
cout << "Octal Value " << octalValue << endl;
c /= 1000;
}
cout << "Final Octal Value: " << octalValue << endl;
}
system("pause");
return 0;
}
答案 0 :(得分:2)
这看起来过于复杂。没有必要涉及浮点数学,它很可能会引入问题。
当然,显而易见的解决方案是使用预先存在的函数来执行此操作(如{ char buf[32]; snprintf(buf, sizeof buf, "%o", binaryValue); }
并完成,但如果您真的想“手动”执行此操作,则应考虑使用位-operations:
binaryValue & 3
屏蔽三个最低位。这些将是你的下一个八进制数字(三位是0..7,这是一个八进制数字)。binaryValue >>= 3
来移动数字以使三个新位进入最低位置答案 1 :(得分:1)
它不理解你的代码;它似乎太复杂了。但是一个
事情是肯定的,如果你正在转换内部表示
八进制,你必须在某个地方除以8,然后做一个% 8
某处。我没有看到他们。另一方面,我看到了两者
10和1000的操作,都不应该存在。
对于初学者,您可能想要编写一个转换的简单函数
一个值(最好是某个类型的unsigned
- 获取unsigned
在担心标志之前使用任何基数,例如:
//! \pre
//! base >= 2 && base < 36
//!
//! Digits are 0-9, then A-Z.
std::string convert(unsigned value, unsigned base);
这不应该超过大约5或6行代码。但是注意,
普通算法以相反的顺序生成数字:如果你是
使用std::string
,最简单的解决方案是push_back
每个数字,
然后在返回之前调用std::reverse
。否则:a
C风格char[]
效果很好,只要你足够大。
(sizeof(unsigned) * CHAR_BITS + 2
绰绰有余,即使是
已签名,即使最后有'\0'
,如果您不需要,也不需要
返回一个字符串。)只需将指针初始化为buffer +
sizeof(buffer)
,并在每次插入数字时预先递减。至
构造你返回的字符串:
std::string( pointer, buffer + sizeof(buffer) )
应该做到这一点。
至于循环,结束条件可能只是value == 0
。
(每次你都会将value
除以base
,所以你就是这样
保证达到这个条件。)如果你使用do ... while
,
而不只是while
,你也保证至少有一位数
输出。
(我发布代码要容易得多,但是从那以后 这显然是家庭作业,我认为最好只是给出指示 关于需要做什么。)
编辑:我已添加了我的实施,并对您的新内容发表了一些评论 代码:
首先是评论:有一个非常误导的提示:“输入一个
二进制数“听起来像用户应输入二进制;如果你是
读入int
,输入的值应为十进制。还有
我仍然是% 1000
和/ 1000
以及% 10
和/ 10
了解。无论你做什么,如果没有%
8
和/ 8
,那就不对了。试一试:输入"128"
,例如,看看你得到了什么。
如果你想输入二进制文件,那么你真的必须输入一个 字符串,并自己解析。
我的转换代码本身就是:
//! \pre
//! base >= 2 && base <= 36
//!
//! Digits are 0-9, then A-Z.
std::string toString( unsigned value, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buffer[sizeof(unsigned) * CHAR_BIT];
char* dst = buffer + sizeof(buffer);
do
{
*--dst = digits[value % base];
value /= base;
} while (value != 0);
return std::string(dst, buffer + sizeof(buffer));
}
如果你想解析输入(例如二进制),那么就像是 以下应该做的诀窍:
unsigned fromString( std::string const& value, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
unsigned results = 0;
for (std::string::const_iterator iter = value.begin();
iter != value.end();
++ iter)
{
unsigned digit = std::find
( digits, digits + sizeof(digits) - 1,
toupper(static_cast<unsigned char>( *iter ) ) ) - digits;
if ( digit >= base )
throw std::runtime_error( "Illegal character" );
if ( results >= UINT_MAX / base
&& (results > UINT_MAX / base || digit > UINT_MAX % base) )
throw std::runtime_error( "Overflow" );
results = base * results + digit;
}
return results;
}
它比toString
更复杂,因为它必须处理所有种类
可能的错误条件。它仍然可能比你简单
需要;你可能也想修剪空白等(甚至忽略
他们:输入01000000
比0100 0000
更容易出错。
(另外,由于尾随,find
的结束迭代器有一个- 1
'\0'
编译器插入digits
。)
答案 2 :(得分:0)
实际上我不明白为什么你需要这么复杂的代码来完成你需要的东西。
首先,没有从二进制转换为八进制这样的事情(转换为/从十进制转换等同样如此)。机器总是以二进制方式工作,没有什么可以(或应该)做的。
这实际上是格式化的问题。也就是说,你如何打印一个数字作为八进制,你如何解析八进制数的文本表示。
修改强>
您可以使用以下代码在任何基地打印一个数字:
const int PRINT_NUM_TXT_MAX = 33; // worst-case for binary
void PrintNumberInBase(unsigned int val, int base, PSTR szBuf)
{
// calculate the number of digits
int digits = 0;
for (unsigned int x = val; x; digits++)
x /= base;
if (digits < 1)
digits = 1; // will emit zero
// Print the value from right to left
szBuf[digits] = 0; // zero-term
while (digits--)
{
int dig = val % base;
val /= base;
char ch = (dig <= 9) ?
('0' + dig) :
('a' + dig - 0xa);
szBuf[digits] = ch;
}
}
示例:
char sz[PRINT_NUM_TXT_MAX];
PrintNumberInBase(19, 8, sz);
答案 3 :(得分:0)
当你想要一个不同基数的数字时,OP要求生成的代码是你的科学计算器会做的。
我认为你的算法错了。只是看着它,我看到一个平方的功能。为什么?有一种简单的数学方法可以做你正在谈论的事情。获得数学部分后,就可以将其转换为代码。
如果你有铅笔和纸,没有计算器(类似于不使用预制功能),方法是取你所在的基础,将其改为基础10,然后改为你需要的基础。在你的情况下,基数为8,基数为10,基数为2.
这应该让你开始。你真正需要的是带有模数的if / else语句来获得余数。 http://www.purplemath.com/modules/numbbase3.htm
然后你必须弄清楚如何获得你想要的输出。也许将余数存储在数组中或输出到txt文件。
(对于像这样的问题,我想用应用数学加倍专业的原因)
由于你想要从十进制0-256转换,所以最简单的做函数,比如称它们为int binary(),char hex()和int octal()。首先执行二进制和八进制,因为它们只能由整数表示,因为它是最简单的。
答案 4 :(得分:0)
#include <cmath>
#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdlib>
using namespace std;
char* toBinary(char* doubleDigit)
{
int digit = atoi(doubleDigit);
char* binary = new char();
int x = 0 ;
binary[x]='(';
//int tempDigit = digit;
int k=1;
for(int i = 9 ; digit != 0; i--)
{
k=1;//cout << digit << endl;
//cout << "i"<< i<<endl;
if(digit-k *pow(8,i)>=0)
{
k =1;
cout << "i" << i << endl;
cout << k*pow(8,i)<< endl;
while((k*pow(8,i)<=digit))
{
//cout << k <<endl;
k++;
}
k= k-1;
digit = digit -k*pow(8,i);
binary[x+1]= k+'0';
binary[x+2]= '*';
binary[x+3]= '8';
binary[x+4]='^';
binary[x+5]=i+'0';
binary[x+6]='+';
x+=6;
}
}
binary[x]=')';
return binary;
}
int main()
{
char value[6]={'4','0','9','8','7','9'};
cout<< toBinary(value);
return 0 ;
}