欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 进制转换,base可能为负数

进制转换,base可能为负数

2025/3/31 21:36:04 来源:https://blog.csdn.net/Sti1lWater/article/details/146608424  浏览:    关键词:进制转换,base可能为负数

0x01 特殊:base=-2

LeetCode

0x02 前置知识:c++ %规则

我们需要知道,在 C C C++ 中,余数的符号取决于被除数,也即,a%b=c c c c 的符号取决于 a a a 的符号,即, a a a 是什么符号, c c c 就是什么符号,与 b b b 的符号无关。

int a[4] = {11, 11, -11, -11};
int b[4] = {2, -2, 2, -2};
for(int i = 0; i < 4; i ++ )cout << a[i] / b[i] << "..." << a[i] % b[i] << endl;

输出结果为:

5...1
-5...1
-5...-1
5...-1

另外,a/b=c c c c 的符号是显而易见的,如果 a a a b b b 同符号, c c c 就是正号,反之,如果 a a a b b b 异号, c c c 就是负号。
知道了上述规则,a/b=c..d c c c d d d 的值我们就可以自己求解了。

0x03 前置知识:取整规则

C C C++ 和 J a v a Java Java 是向 0 0 0 取整, P y t h o n Python Python 是下取整

0x04 十进制转其他进制 – 辗转相除法

如果将一个 10 10 10 进制转换为一个 2 , 3 , 4 , . . . . n 2,3,4,....n 2,3,4,....n(正数) 进制,是很容易的,我们直接辗转相处然后对字符串 r e v e r s e reverse reverse 就行了。当然,如果数字不够用,还需要用到 a , b , c . . a,b,c.. a,b,c..
但是今天做到 0x01 这道题时,着实让我烧脑筋了,因为我想知道一种通用的解法,不仅仅局限于进制为 − 2 -2 2 的情况,对于 − 3 , − 4 , − 5 -3,-4,-5 3,4,5 甚至于 2 , 3 , 4 2,3,4 2,3,4 都可以通用的解决。
其实,当进制为负数时主要有一个问题:那就是,辗转相除时,余数可能为负数,此时该怎么办呢?

首先,余数为负数说明被除数肯定是个负数( 0 x 02 0x02 0x02)。
并且被除数(也就是 b a s e base base)也肯定是个负数,因为我们规定输入的十进制数都是正数,而这里被除数(十进制数)成了负数,说明此时除数肯定是负数。

好了,现在回归正题,我们肯定不能让余数为负数啊,所以我们需要把它转换为非负数。
直接告诉你方法:如果余数为负数,就加上进制的绝对值。
为什么这么做是正确的?因为我们可以很自然的修改商。
例如:十进制数为 a = − 11 a=-11 a=11,进制为 b = − 2 b=-2 b=2,商为 c c c,余数为 d d d
-11/-2=5...-1,因此我们需要让 d = − 1 + a b s ( − 2 ) = 1 d=-1+abs(-2)=1 d=1+abs(2)=1,但是修改了 − 1 -1 1 c ∗ b + d = = a c*b+d==a cb+d==a 的等价关系就不成立了。
因此,我们还需要修改商,这里,我们只需要让商直接 + 1 +1 +1 就好了。
因为让余数加上进制的绝对值就相当于让余数减去进制(前面证明了,进制一定是负数),所以我们需要让商 + 1 +1 +1,相当于把减去的进制加上了。
这样:(c+1)*b+(d-b)==c*b+d==a 依然成立。

如果我们不是让余数加上进制的绝对值,而是加上了一个其他的数,此时我们仍然需要通过改动商来维护等价关系(不可能修改进制,修改除数没意义)。
但是此时,商可能变成一个浮点数,例如,余数加上了 k k k,那么我们需要让 (c+q)*b+(d+k)==c*b+d 成立。
就需要让 q = − k / b q=-k/b q=k/b q q q 未必是个整数。

0x05 通解:abs(bsae)<10

b a s e > = 10 base>=10 base>=10 时需要用到 a , b , c , . . . . a,b,c,.... a,b,c,....,这应该不会考到,也不需要用, 16 16 16 进制就很好了。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cassert>
#include <cmath>using namespace std;const int N = 1024 * 1024;// 将正整数n转换为base进制并输出结果
// abs(base) < 10 && base != 0
string toBaseStr(int n, int base);// 测试程序
void test();
string toBaseStr(int n, int base);int main()
{test();return 0;
}string toBaseStr(int n, int base) 
{assert(base);if(n == 0)  return "0";string res("");while(n) {int c = n % base;n /= base;if(c < 0) c -= base, n ++ ;res += to_string(c);}reverse(res.begin(), res.end());return res;
}static void doTestBase(int base)
{int debuger = 0;for(int i = 0; i < N; i ++ ){string s = toBaseStr(i, base);string t = s;int n = s.size();int test = 0;reverse(t.begin(), t.end());for(int j = 0; j < n; j ++ )if(t[j] != '0') test += (t[j] - '0') * pow(base, j);if(test != i)cout << "[Wrong" << ++ debuger << "]: " << i << "->" << s << " is " << test << endl;// else //     cout << "[Accpet]: " << i << "->" << s << " is " << test << endl;}if(!debuger)cout << "[Accept] base = " << base << endl;
}void test()
{clock_t start = clock();for(int i = 2; i < 10; i ++ ){doTestBase(i);doTestBase(-i);}printf("CPU Time = %.2lfs\n", (clock() - start) * 1.0 / CLOCKS_PER_SEC);
}

0x06 参考

ref here

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词