zoukankan      html  css  js  c++  java
  • 关于负数取模与负数除法取整(P1017 进制转化)

    首先,除法总是向0取整的,即2/3=0,-2/3还是0,因此可以把负号拿出来变成-(2/3).提取(除数或被除数)负号总是可行的,这还包括-2/-3,2/-3之类的情况.

    而负数的取模运算如a%b,标准规定其可由a-(a/b)*b得出,那么可知

      1.运算结果的符号与a相同.    (因为减号右侧的绝对值一定不大于a)

      2.(这意味着)b的符号不影响运算结果.    (把上式中的b换为-b,提取符合后与原式相等)

    所以对于涉及负数取模的运算a%b,如果你单纯地想要得到等价的运算结果,可以用这样的方法思考:

    • 用b的绝对值替换b
    • 把a的符号提取出来
    • 进行两正整数之间的取模,并加上a的符号

    下面这题中,需要你对负数的取模,整除进行特殊处理,如负数除以负数求正余数,负数除以负数"向下"取整.

     来看看-15转为-2进制的过程.

    不停地用-2为除数去除-15,并取余数(正数)为结果中的一位.

    -15/-2=7余1,看上去是符合的,然而此时1x(-2)4+1x(-2)3=8,不为7.

    当进行正数的进制转化时,每次除总是向下取整取余数为结果,而进行负数的进制转化时,每次除总是向0,也就是向上取整了,我们需要向下取整.

    想要这样操作只需要进行一下判断再处理就可以了.

    现在,每次除之后想要得到一个正余数,a%b若左侧数为正数,不需要额外处理,如果为负数,写为-b+a%b即可.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    char num[30] = "0123456789ABCDEFGHIJKLMN";
    
    void slove(int n, int m) {
        if (n > 0 || n % m == 0) {
            slove(n / m, m);
            putchar(num[n % m]);
        } else if (n < 0) {
            slove(n / m + 1, m);
            putchar(num[-m + n % m]);
        }
    }
    
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        printf("%d=", n);
    
        slove(n, m);
    
        printf("(base%d)", m);
    
        return 0;
    }
    P1017
  • 相关阅读:
    UVA1452|LA4727-----Jump------经典的约瑟夫公式的变形(DP)
    ORM框架Hibernate (四) 一对一单向、双向关联映射
    heaters
    对SIGQUIT的实验 & Java dump
    【Todo】单例模式各种实现方式及并发安全
    【转载】Spark系列之运行原理和架构
    git本地文件回滚操作
    Java异常与运行时异常,以及与线程的关系
    Callable与Future、FutureTask的学习 & ExecutorServer 与 CompletionService 学习 & Java异常处理-重要
    Linux系统负载排查
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14436408.html
Copyright © 2011-2022 走看看