精华内容
下载资源
问答
  • C语言中3/-2=?3%-2=?你确定答案吗

    千次阅读 2020-05-19 09:56:51
    关注、星标公众号,直达精彩内容抛砖引玉C语言负数除以正数,与正数除以负数或者负数除以负数的余数和商,正负谁定呢?-3 / 2 = ?; -3 % 2 = ?; 3 / (-2) = ?...

    关注、星标公众号,直达精彩内容

    抛砖引玉

    C语言负数除以正数,与正数除以负数或者负数除以负数的余数和商,正负有谁定呢?

    -3 / 2 = ?;
    -3 % 2 = ?;
    3 / (-2) = ?;
    3 % (-2) = ?;
    (-3) / (-2) = ?;
    (-3) % (-2) = ?;
    

    前提假设

    假定我们让 a 除以 b,商为 q,余数为 r:q = a / b;r = a % b;这里,不妨假定 b 大于 0。我们希望 a、b、q、r 之间维持怎样的关系呢?

    1. 最重的一点,我们希望 q * b + r == a,因为这是定义余数的关系。

    2. 如果我们改变 a 的正负号,我们希望这会改变 q 的符号,但这不会改变 q  的绝对值。

    3. 当 b>0 时,我们希望保证 r >= 0 且 r < b。

    例如,如果余数用于哈希表的索引,确保它是一个有效的索引值很重 。这三条性质是我们认为整数除法和余数操作所应该具备的。很不幸的是,它们不可能同时成立。

    举例说明

    考虑一个简单的例子:3/2,商为1,余数也为1。此时,第1条性质得到了满足。(-3)/2 的值应该是多少呢?如果满足第2条性质,答案应该是-1,但如果是这样,余数就必定是-1,这样第3条性质就无法满足了。如果我们首先满足第3条性质,即余数是 1,这种情况下根据第1条性质则商是-2,那么第2条性质又无法满足了。

    因此,C语言或者其他语言在实现整数除法截断运算时,必须放弃上述三条原则中的至少一条。大多数程序设计语言选择了放弃第 3 条,而改为求余数与被除数的正负号相同。这样,性质1性质2就可以得到满足。大多数C编译器在实践中也都是这样做的。

    然而,C语言的定义只保证了性质1,以及当 a>=0 且 b>0 时,保证|r| < |b|以及 r>=0。后面部分的保证与性质2 或者性质3 比较起来,限制性弱得多。

    实例论证

    C 语言的定义虽然有时候会带来不需的灵活性,但大多数时候,只要编程者清楚地知道要做什么、该做什么,这个定义对让整数除法运算满足其需要来说还是够用了的。例如,

    假定我们有一个数 n,它代表标识符中的字符经过某种函数运算后的结果,我们希望通过除 法运算得到哈希表的条目 h,满足 0<=h<HASHSIZE。又如果己知 n 恒为非负,那么我们只需要像下面一样简单地写:

    h=n%HASHSIZE:
    

    然而,如果 n 有可能为负数,而此时 h 也有可能为负,那么这样做就不一定总是合适的了。不过,我们已知 h>-HASHSIZE,因此我们可以这样写:

    h = n % HASHSIZE;
    if(n < 0)
      h += HASHSIZE;
    

    测试代码:

    #include <stdio.h>
    main()
    {
         int a=-3, b=2,c=3,d=-2;
         int q,r,m,n,x,y;
         q = a / b;
         r = a % b;
         m = c / d;
         n = c % d;
         x = a / d;
         y = a % d;
         printf("q=%d, r=%d\n" , q , r);
         printf("m=%d, n=%d\n" , m , n);
         printf("x=%d, y=%d\n" , x , y);
    }
    

    最终结论

    翻阅资料得出,这个问题在C语言早期是没有固定规定的,所以一些书中会有谁这种行为值不固定,是编译器而内决定,但是现在C99中有强制规定了,要求对容于整型数a,b,必然满足 a%b==a-(a/b)b,如果第一操作数为负,则得到的模为负;如果第一操作数为正,则得到的模为正

    所以遇到这样的问题一般计算的方法是:余数与被除数(即分子的符号)相同;先将各个带符号的数全部取正值再做除法,再根据负号的个数确定商的符号

    注意的点

    当然在实际的项目中,更好的做法是,程序在设计时就应该避免 n 的值为负这样的情形,并且声明 n 为无符号数。


    推荐阅读(点击标题可跳转阅读)【编程之美】用C语言实现状态机(实用)【编程之美】超时重传,滑动窗口,可靠性传输原理C语言实现
    【编程之美】论嵌入式架构的重要性
    
    
    
    展开全文
  • 我想问的是网上资料说的都是符号数int 向无符号数unsigned int转化 ,因为在32位机上,int是32位,范围–2,147,483,648 to 2,147,483,647 ,unsigned int是32位,范围0 to 4,294,967,295,所以int向范围更大的...
  • C语言之猪的星期五

    2020-05-31 14:27:34
    猪的星期五欢迎进入我的C语言世界题目答案本题感悟 欢迎进入我的C语言世界 ...n是一个非负数且不大于400。 这里一些你要知道的: 1.1900年1月1日是星期一。 2.4,6,11和9月30天。其他月份除了2月

    欢迎进入我的C语言世界

    题目

    Problem Description

    "13号是星期五"是一个不寻常的日子吗?13号在星期五比在其他日少吗?

    猪们想了解一下这个问题,于是他求助于善于编程的你。请你写一个程序来计算在n年里13日落在星期一、星期二……星期日的次数。这个测试从1900年1月1日到1900+n-1年12月31日。n是一个非负数且不大于400。

    这里有一些你要知道的:
    1.1900年1月1日是星期一。
    2.4,6,11和9月有30天。其他月份除了2月有31天。闰年2月有29天,平年2月有28天。
    3.年份可以被4整除的为闰年(1992=4*498 所以 1992年是闰年,但是1990年不是闰年)
    4.以上规则不适合于世纪年。可以被400整除的世纪年为闰年,否则为平年.所以,1700,1800,1900和2100年是平年,而2000年是闰年。

    猪们喜欢人品高的人,如果你预先算好数据,它们会认为你的人品值为0。

    Input

    输入包含多组测试数据,请处理到EOF结束。
    每组数据包括一个整数n.

    Output

    每组数据输出一行,为7个以空格分隔的整数,它们代表13日是星期六,星期日,星期一……星期五的次数。

    Sample Input

    20

    Sample Output

    36 33 34 33 35 35 34

    答案

    下面展示 实现代码

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    int day[7];
    int month[12]={18,15,18,17,18,17,18,18,17,18,17,18};//每个月13号以后剩下的日子 
    int main()
    {
    	int n;
    	int Day;
    	while(scanf("%d",&n) != EOF)
    	{
    		memset(day,0,sizeof(day));
    		Day = 0;
    		for(int i = 1900; i < 1900+n; i++)
    		{
    			for(int j = 1; j < 13; j++)
    			{
    				Day += 13;//直接跳到13号 
    				day[Day%7]++;//13号对应的星期 
    				Day += month[j-1];//13号之后的日子 
    				if(j==2 && ((i%4==0 && i%100!=0) || i%400==0))//闰年 
    				{
    					Day++; //闰年的二月多一天
    				}
    			} 
    		}
    		printf("%d %d %d %d %d %d %d\n", day[6], day[0], day[1], day[2], day[3], day[4], day[5]);
    	}
    	return 0;
    } 
    
    

    本题感悟

    本块内容可能来自课本或其他网站,若涉及侵权问题,请联系我进行删除,谢谢大家啦~

    一个是month数组是应用,一个是本题的思想

    以上。

    展开全文
  • 2. 循环录入5个人的年龄并计算平均年龄,如果录入的数据出现负数或大于100的数,立即停止输入并报错. 3. 实现要求用户一直输入QQ号码和密码,只要不是123456、888888就一直提示要求重新输入,如果正确则提登录成功. 4...
  • 假设我们在对符号值使用二进制补码云端的32位...我的理解是,x和y都为负数。转为无符号是不是都为正的了,它们的位级虽然相同,编译器解释应该不同啊,比如-3*-3 -3位级为1101。转为无符号,编译器不该是解释为13吗?
  • 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 进阶: 尽可能想出更多的解决方案,至少三种不同的方法可以解决这个问题。 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗? 示例 1...

    189. 旋转数组


    给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

    进阶:

    尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
    你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

    示例 1:

    输入: nums = [1,2,3,4,5,6,7], k = 3
    输出: [5,6,7,1,2,3,4]
    解释:
    向右旋转 1 步: [7,1,2,3,4,5,6]
    向右旋转 2 步: [6,7,1,2,3,4,5]
    向右旋转 3 步: [5,6,7,1,2,3,4]



    解法1

    一次旋转一次,数组最后一个元素移动到数组头部,数组其余元素向后移动一次。一共移动k次。

    在这里插入图片描述
    但是这种解法效率太慢了,会超出时间限制。



    代码示例:

    void rotate1(int* nums, int numsSize, int k) {
    
    	k %= numsSize; //只移动余数次。
    	int tmp = 0;
    	int i;
    	for (i = 0;i < k;i++)
    	{
    		tmp = nums[numsSize - 1];
    
    		int j;
    		for (j = numsSize - 1;j > 0;j--)
    		{
    			nums[j] = nums[j - 1];
    		}
    
    		nums[0] = tmp;
    	}
    
    }
    




    解法2:三步逆序

    假设要移动k次,将数组分为arr1和arr2两个数组,arr2的大小为k。分别逆序。

    在这里插入图片描述

    arr1和arr2逆序完毕,最后把整个数组逆序。

    在这里插入图片描述

    旋转完毕。
    在这里插入图片描述

    时间复杂度:n*k
    空间复杂度:O(1)




    代码示例

    //实现逆序
    void reverse(int* nums, int left, int right)
    {
    	while (left < right)
    	{
    		int tmp = nums[left];
    		nums[left] = nums[right];
    		nums[right] = tmp;
    		left++;
    		right--;
    	}
    
    }
    
    
    void rotate(int* nums, int numsSize, int k) {
    
    	k %= numsSize; //只让余数移动。节省性能。
    
    	reverse(nums, 0, 0 + (numsSize - k) - 1); //arr1旋转一次
    	reverse(nums, (numsSize - k), numsSize - 1);//arr2旋转一次
    	reverse(nums, 0, numsSize - 1);//整体旋转一次
    
    }
    
    展开全文
  • 不得不说位操作确实是一...与1做与运算&,然后统计1的个数,等等,诈,万一是负数的话,这不就成死循环了吗,思考片刻,简单,这次就让1不断的往左边移动,然后去与整数做与运算&,这也是可以的。。。再等等,万一这

    不得不说位操作确实是一个十分不错的操作,只是简单的几步就足以笑傲江湖,今天看两道简单位操作面试题

    二进制中1的个数:实现一个函数,输入一个整数,输出该整数二进制中1的个数

    分析:这还不简单,直接让这个整数依次往右边移动一位,与1做与运算&,然后统计1的个数,等等,有诈,万一是负数的话,这不就成死循环了吗,思考片刻,简单,这次就让1不断的往左边移动,然后去与整数做与运算&,这也是可以的。。。再等等,万一这台机器是坑爹的128位,就算是32位那效率也是不高的啊,思考良久,终于有了一个稳妥的办法

    稳妥办法: 举个例子,假设一个整数的二进制序列是1100,那么将二进制序列-1会得到1011,此时再将1100&1011=1000,哈哈,想到了吧只要将整数&(整数-1)就会得到剩下的1,此等解法只需要比较整数中1的个数次即可。

    部分代码(C/C++)

    int Num(int n){
        int count=0;
        while(n){
            count++;
            n=(n-1)&n;
            }
        return count;
        }

    嗯,效果不错,算是一个比较好的解法了。

    三种错误的处理方式:API、全局变量、异常,需要考虑的是功能测试、边界测试、负面测试

    数值的整数次方:实现一个pow()函数,不用考虑大数问题

    分析:这还不简单,直接用一个for循环就可以解决战斗,但有诈,万一这个出现负数和0的情况那不就GG了,所以得考虑边界测试和负面测试,但还是可以接受的,加入0和负数的判断即可,但要注意double类型比较“==”时不准确,一般想到这就差不多了,但是凡是都有例外,这里有个更好的解法。

    稳妥办法: 由公式an=an/2an/2(n)an=an1an1an
    这个公式实在是太棒了,虽然很简单,但是却十分的奏效,利用它结合神奇的递归,就可以以简单的代码实现上面的题目了。

    完整代码(C/C++)

    #include<stdio.h>
    double power(double base,unsigned int e){
        if(e==0)
        return 1;
        if(e==1)
        return base;
        double result=power(base,e>>1);
        result*=result;
        if(e&1==1)
            result*=base;
        return result;
    }
    int main(){
        double base;
        scanf("%lf",&base);
        unsigned int e;
        scanf("%d",&e);
        if(base-0<0.0001){
            printf("input error");
            return 0;
            }
        double s=power(base,e);
        printf("the pow(%lf,%d)=%lf",base,e,s);
        return 0;
    }

    这里写图片描述

    小结

    今天上线的两道位操作题目比较简单,重点是梳理位操作在实战中的应用,因为在讲究效率的当代,一个好的操作是会起到很棒的效果的,不得不说,剑指offer确实是一本好书,接下来继续辛勤工作。。

    展开全文
  • 近期个朋友在程序中使用了对16进制数做负数移位(编译器是gcc),本人最次产生好奇。所以研究了一些。 对一个数做负数位移位的操作是不规范的,可是是可行的。 详细样例: char tmp = 0x10; tmp = tmp <&...
  • 负数转换为无符号整型的理解及应用负数转换为无符号类型的理解及应用符号整型...一篇博客中这样写到:当执行一个运算时,若它的一个运算数是符号的,而另一个数是无符号的,那么C语言会隐式地将符号参数强制转换
  • 和指针----读书笔记1>

    2017-07-13 20:42:22
    那么C语言中主要几类数据? 数据如何访问?数据如何存储,这几个方面是我们事先需要掌握的。   从我们生活实际应用的角度出发:数据小数和整数、正负之分; 那么在C语言中,是这样的吗?该怎么定义正负数、小数...
  • 和指针---读书笔记1>

    2017-08-29 21:43:00
    那么C语言中主要几类数据? 数据如何访问?数据如何存储,这几个方面是我们事先需要掌握的。 <3.1 基本数据类型> 从我们生活实际应用的角度出发:数据小数和整数、正负之分; 那么在C语言中,是这样的...
  • 如果想要强行转换变量类型,可以使用与C语言相同的函数settype()。 2.5 变量与常量 可能你已经注意到,变量都一个美元符号($)的前缀。所有变量都是局部变量,为了使得定义的函数中可以使用外部变量,使用...
  • C学习深入学习总结

    2017-11-03 16:59:17
    8.8 C语言字符串这个数据类型吗? 11 8.9 对字符串进行操作的时候,是否为字符串结尾符预留存储位置?不然的话容易造成非常访问内存。 11 9 数组 12 9.1 你肯定知道,定义“int a[10]; ”, a[10] 这个元素是...
  • C语言程序设计》 实验指导书 山东水利职业学院 目 录 实验一 C语言程序初步 2 实验二 数据类型、运算符和表达式 3 实验四 循环结构(1) 6 实验五 循环结构(2) 9 实验六 函数(1) 12 实验七 函数(2) 14 ...
  • PHP新手上路.CHM

    2010-04-12 11:48:26
    # 负数 $a = 0123; # 八进制数 (等于十进制数的83) $a = 0x12; # 十六进制数(等于十进制数的18) $a = 1.234; # 浮点数"双精度数" $a = 1.2e3; # 双精度数的指数形式 字符串 字符串可以由单引号或双引号引出的字段...
  • 《数据结构 1800题》

    热门讨论 2012-12-27 16:52:03
    8. 一个算法具有 5个特性: (1)穷性 、 (2)确定性 、 (3)可行性 ,零个或多个输入、一个或多个输出。 《数据结构 1800题》 9.已知如下程序段 FOR i:= n DOWNTO 1 DO {语句 1} BEGIN x:=x+1;...
  • 负数的反码与原码如下关系: 符号位相同(仍用1表示),其余各位取反(0变1,1变0)。 补码由该数反码的最末位加1求得。 第 二 章 C++简单程序设计 2-1 C++语言那些主要特点和优点? 解: C++语言的主要特点表现在...
  • 返回负数,如果是之后,返回正数。 函数 <ul><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions">Function</a></li> 说起来Js的核心是什么?那就是函数...
  • LINGO软件的学习

    2009-08-08 22:36:50
    可以把集、集成员和集属性同C语言中的结构体作个类比。如下图: 集 ←→ 结构体 集成员 ←→ 结构体的域 集属性 ←→ 结构体实例 LINGO内置的建模语言是一种描述性语言,用它可以描述现实世界中的一些问题,然后再...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

c语言有负数吗

c语言 订阅