平衡三进制小数详解与进制转换

        标准三进制是“逢三进一,退一还三”的机制,平衡三进制与之类似,但就是偏移了一下变得对称了,平衡三进制与标准三进制可以相互转换,但这样显得有点多余了,所以这里只讲平衡三进制与十进制的转换。

数字系统的由来

远古时代:原始人通过绳子系绳结、在石头或木头上刻划痕的方式来记数,这种计数方法简单,但难数,时间过久了就难以分清那个是那个了。

非位置化数字系统:罗马数字(经典代表),罗马数字共有7个,分别是Ⅰ(1)、Ⅴ(5)、Ⅹ(10)、Ⅼ(50)、Ⅽ(100)、Ⅾ(500)和Ⅿ(1000),若为ⅤⅤⅤ则表示15。

位置化数字系统:现在用的基本都是这个,如:二进制、平衡三进制、十进制等,计算金钱的用的也是位置化数字系统,它与我们的生活息息相关。

位置化系统的位权

        以小数点为分界线,整数的第一位为0,向前一位为1,再向前一位为2,依次类推;然后是小数部分,第一位为-1,向后一位为-2,再后一位为-3依次类推;位置化系统的位权作为系数,若基数为十,则称为十进制、若基数为2,则称为二进制、若基数为3,则称为标准三进制或平衡三进制,如下表所示:

位置化系统的位权210-1-2-3
十进制数(125.345)125.345
10^210^110^010^-110^-210^-3
平衡三进制数(1TT.111)1TT.111
3^23^13^03^-13^-23^-3

平衡三进制的小数表示

        这是一个绕不开的问题,要想搞明白平衡三进制的小数如何表示,怎么来的那就先搞懂十进制的小数与整数,如上表十进制数为125.345,也就是:

1*10^2 + 2*10^1 + 5*10^0 + 3*10^-1 + 4*10^-2 + 5*10^-3

=100 + 20 + 5 + 0.3 + 0.04 +0.005

=125.345

所以平衡三进制1TT.111(十进制5.5),可表示为:

1*3^2 + T*3^1 + T*3^0 + 1*3^-1 + 1*3^-2 + 1*3^-3

=9 + (-3) + (-1) + (1/3) + (1/9) + (1/27)

大概为5.4,要精确到后5位,这样的结果较为准确,1TT.11111重新计算结果为5.46095.

平衡三进制转换的运算规则

        平衡三进制作为标准三进制的一个变体,所以还是以标准三进制出发,然后再进一步去除得到最终的平衡三进制转换方法。

标准三进制转平衡三进制的方法

        平衡三进制的转转换法中,需要先写出一个给定的数 x 在标准三进制中的表示。当 x 是用标准三进制表示时,其数字的每一位都是 0、1 或 2。要转化为平衡三进制,需要从低位到高位操作

  1. 遇到 0 和 1,可直接跳过
  2. 遇到 2,当前位改为 T,向前进位加上 1
  3. 遇到 3,当前位改为 0,向前进位加上 1

十进制整数直接转平衡三进制的方法

    每次进行模3取余,最后进行倒序读取,有以下得余数表示,
    -2    -1    0    1    2(正数与负数分别对2与-2处理)
    -1、0、1合法的,故不处理
    若商为-2,则将商减一,再除于3得到新商,然后余数变成1
    若商为 2,则将商加一,再除于3得到新商,然后余数变成-1

        如上图所示,先用连除法,不断的除于3取余,商至到为0结束,标准三进制得到的数为20,然后用第一个规则(标三转平三),得到1T0;然后直接跳过标准三进制,当商为 2,则将商加一,再除于3得到新商为1,然后余数变成-1,直接得1T0,这样就不用转来转去了。

十进制小数直接转平衡三进制的方法

    每次进行乘3取整,正数结果为正,负数则为负,那么会有以下得整数表示,
    -2    -1    0    1    2(正数与负数分别对2与-2处理)
    若为正数,则遇到0或1直接跳过,遇到2当前位改T,向前进1
    若为负数,则遇到0或1直接跳过,遇到-2当前位改1,向前进T

        如上图所示,小数用的是连乘法,不断的乘于3取整,可以精确到某一位或为0为止,标准三进制得到0.3为0.022002,然后用第一个规则(标三转平三),得到0.10T01T;然后直接跳过标准三进制,遇到0或1直接跳过,遇到2当前位改T,向前进1,也就是向上进1,直接得到0.10T01T,得到正数直接可以(1变T,T变1)变为负数,也可以再算一次。

总结:

整数部分与小数部分要分开算,得到相应结果,最后再相加在一起就行了;

整数部分使用连除法,采用倒序读取余数,即可以得结果;

小数部分使用连乘法,采用正序读取整数,即可以得结果;

十进制浮点数转平衡三进制数的实现

        先观察上图,平衡三进制数,它的小数很有特点,就是以0.5或-0.5为分界,它过了这条界则要向前进一位,上面与下面的数也是对称,所以如果是4.5转成平衡三进制,则为11.11111111,当为4.6时,则0.6为1.TT11和4的11相加,则整数部分要进位,得到1TT.TT11TT11TT,其中小数部分没变,整数变了,所以当小数与整数合体时,大于0.5或小于-0.5的小数要进位,会丢失一位,所以要在前面补0就行了。

        然后结合上面的方法,十进制数的整数与小数分别转为平衡三进制,再将它们结合在一起就可以了,这里用C++成功实现了上述方法,采用的是deque容器数据结构,它可以高效的在前后两端推入数据,类似于数组但不是数组,因为要进位所以用deque容器,当输入去的数据再拿出来改时方便,平衡三进制的小数和它的分数其实都各有优势,但我更喜欢分数(方便计算,误差小)。

        平衡三进制和十进制一样,用小数点分隔整数部分和小数部分;在平衡三进制中,四舍五入和截位的操作是等效的;平衡三进制可以像十进制一样,可以用小数来表示分数;小数可分为:有限小数、无限循环小数、无限不循环小数,小数中除无限不循环小数外都可以用分数来表示;最后给出写了几天,终于写出的十进制浮点数转平衡三进制的C++代码:

#include <iostream>
#include <deque>
#include <algorithm>using namespace std;
// 将deque容器内数据展示出来
void showDequeArray(const deque<char>& charDeque) {for (char element : charDeque) {cout << element;}cout << endl;
}
// 将数字转为char
char toTargetChar(int n) {switch (n) {case -1: return 'T';case 0:  return '0';case 1:  return '1';default: return '\0';}
}//进位操作
void changeCarryChar(deque<char>& originBalancedTernary,char carryChar){//默认要进一位,倒着读取再进位bool isCarry=true;//当前最后一位为originBalancedTernary.size()-1,//前一位为originBalancedTernary.size()-2,//最后一位改写,前一位判断是否再进位,同样要改写for (int i = originBalancedTernary.size()-2; i >= 0; --i) {	//若false则不进位,结束循环if(!isCarry) break;//这是变换进位操作(正数进1,负数进T)switch (originBalancedTernary[i]) {case '0':isCarry=false;originBalancedTernary[i]=carryChar;break;case '1':if(carryChar=='T'){isCarry=false;originBalancedTernary[i]='0';}else if(carryChar=='1'){isCarry=true;originBalancedTernary[i]='T';}break;case 'T':if(carryChar=='1'){isCarry=false;originBalancedTernary[i]='0';}else if(carryChar=='T'){isCarry=true;originBalancedTernary[i]='1';}break;default:break;}}
}//将十进制数转换成平衡三进制数
deque<char> decimalToBalancedTernary(double decimal){deque<char> balancedTernary;//创建 Vector存结果const int maxIterations = 10;//可调整,小数部分的精确位/*获取整数部分,进行转换操作,每次进行模3取余,因为会出现负数,那么会有以下得余数表示,-2	-1	0	1	2(正数与负数分别对2与-2处理)-1、0、1合法的,故不处理若商为-2,则将商减一,再除于3得到新商,然后余数变成1若商为 2,则将商加一,再除于3得到新商,然后余数变成-1*/int integerPart = static_cast<int>(decimal);if(integerPart==0)balancedTernary.push_back('0');//默认为0,则出0while (integerPart != 0) {int remainder = integerPart % 3;//得到余数switch (remainder) {case -1:case  2:balancedTernary.push_back('T');integerPart = (integerPart + 1) / 3;//商加一,除于3是为了得到商break;case  1:case -2:balancedTernary.push_back('1');integerPart = (integerPart - 1) / 3;//商减一,除于3是为了得到商break;default:balancedTernary.push_back('0');integerPart /= 3;//除于3是为了得到商break;}}reverse(balancedTernary.begin(), balancedTernary.end()); // 反转顺序,倒序读取balancedTernary.push_back('.');//添加小数点/*获取小数部分,进行转换操作,每次进行乘3取整,正数结果为正,负数则为负,那么会有以下得整数表示,-2	-1	0	1	2(正数与负数分别对2与-2处理)若为正数,则遇到0或1直接跳过,遇到2当前位改T,向前进1若为负数,则遇到0或1直接跳过,遇到-2当前位改1,向前进T*/double fractionalPart = decimal - static_cast<int>(decimal);//大于0.5或小于-0.5的小数要进位,当小数与整数合体时,会丢失一位,所以要在前面补0if(fractionalPart>0.5 || fractionalPart < -0.5)balancedTernary.push_front('0');for (int i = 0; i < maxIterations; ++i) {fractionalPart*=3;int roundIndex = static_cast<int>(fractionalPart);//乘3后取整的数switch (roundIndex) {case -2:balancedTernary.push_back('1');changeCarryChar(balancedTernary,'T');break;	case 2:balancedTernary.push_back('T');changeCarryChar(balancedTernary,'1');break;default:balancedTernary.push_back(toTargetChar(roundIndex));break;}fractionalPart-=roundIndex;//得到剩下的小数	if (fractionalPart == 0) break;// 如果小数部分已经处理完毕,退出循环}return balancedTernary;
}int main()
{double decimal;cout<<"请输入十进制浮点数,将转换成平衡三进制:"<<endl;cin >> decimal;deque<char> balancedTernary = decimalToBalancedTernary(decimal);showDequeArray(balancedTernary);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/12509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法-排序算法3-插入排序

目录 1.插入排序&#xff1a; 1.介绍&#xff1a; 2.动态图解 3.举例 4.小结插入排序规则 5.插入排序代码 6.运行时间 代码&#xff1a; 运行结果&#xff1a; 1.插入排序&#xff1a; 1.介绍&#xff1a; 数组中n个元素&#xff0c;把这n个待排序元素看成一个有序序…

(Java面试题——基础版)JVM、JRE和JDK的关系

JVM Java Virtual Machine是Java虚拟机 &#xff0c;Java程序需要运行在虚拟机上 &#xff0c;不同的平台有自己的虚拟机 &#xff0c;因此Java语言可以 实现跨平台。JVM 负责将 Java 字节码&#xff08;即编译后的 .class 文件&#xff09;翻译成特定平台上的机器码&#xff0…

直播预告-如何快乐学习亚马逊云科技AWS,玩游戏备考亚马逊云科技云从业者认证?

一边玩一边学习亚马逊云科技云技能&#xff0c;这么好的事尊的假的&#xff1f;本周六&#xff08;5约11日&#xff09;晚20点&#xff0c;亚马逊云科技UG云端夜话Night Talk活动精彩回归&#xff5e; 本次亚马逊云科技UG云端夜话直播是什么&#xff1f; 小李哥这次将在多平台…

分析 vs2019 cpp20 规范的 STL 库模板 function ,源码注释并探讨几个问题

&#xff08;1 探讨一&#xff09;第一个尝试弄清的问题是父类模板与子类模板的模板参数的对应关系&#xff0c;如下图&#xff1a; 我们要弄清的问题是创建 function 对象时&#xff0c;传递的模板参数 _Fty , 传递到其父类 _Func_class 中时 &#xff0c;父类的模板参数 _Ret…

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

基础知识要求&#xff1a; Java&#xff1a;方法、while循环、for循环 Python&#xff1a; 方法、while循环、for循环 题目&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head […

论Java和C++方向选择

目录 1.难度2.就业压力3.岗位选择4.薪资待遇5.选择建议小结 1.难度 Java &#xff0c;C&#xff0c; 测开&#xff0c;整体来说三个方向难度相当。 1.仅从语法角度来看&#xff0c;c 是掌控一切&#xff0c;知识都要懂一点&#xff0c;而java的特点在于省心&#xff0c;都封装…

【C++小语法】引用和内联函数(完结篇)

在使用C语言编程过程中&#xff0c;C语言的要求之严格&#xff0c;编程过程之繁琐&#xff0c;大同小异的重复性工作&#xff0c;令C之父使用C语言编程时也深受其扰&#xff0c;于是乎C兼容C小语法诞生了 一、引用 1.引用概念 在C中&#xff0c;引用&#xff08;Reference&am…

【Android踩坑】 Constant expression required

gradle 8&#xff0c;报错 Constant expression required&#xff1a;意思是case语句后面要跟常量 解决1 单击switch语句&#xff0c;键盘按下altenter&#xff0c;将switch-case语句替换为if-else语句(或者手动修改) 解决2 在gradle.properties中添加 android.nonFinalRes…

【卫星影像三维重建随记】obj模型及其纹理材质文件介绍

obj模型及纹理材质介绍 1.介绍1.1 背景1.2 带有纹理色彩的obj三维模型 2.带有纹理信息obj三维模型文件解析2.1 三维模型数据2.2 obj文件内容2.3mtl文件内容 3 参考 1.介绍 1.1 背景 OBJ格式是一种简单且通用的三维模型文件格式&#xff0c;支持多边形网格和基本的几何体类型&…

leetcode.K站中转(python)

开始准备用dfs深度搜索&#xff0c;发现n100&#xff0c;dfs可能会超时&#xff0c;即使用了剪枝。 class Solution:def findCheapestPrice(self, n: int, flights: List[List[int]], src: int, dst: int, k: int) -> int:length k 2ans float(inf)rec []vis [True]*n…

Golang RPC实现-day01

导航 Golang RPC实现一、主体逻辑设计二、服务设计1、监听和接收请求2、处理请求(1)服务结构体定义(2)确认请求方和服务方编解码格式(3)循环读取请求(4)解析请求的内容(5)响应请求 三、读取和发送数据到连接中代码 Golang RPC实现 先来一个最简单的版本&#xff0c;后续更新。…

Qt学习笔记1.3.4 QtCore-Qt资源系统

文章目录 资源收集文件(.qrc)外部二进制资源内编译(compiled-in)资源压缩使用应用程序中的资源使用库中的资源 Qt资源系统是一种 独立于平台的机制&#xff0c;用于在应用程序的可执行文件中存储二进制文件。如果您的应用程序总是需要一组特定的文件(图标、翻译文件等)&#x…

QT状态机8-使用恢复策略自动恢复属性

当状态分配的属性不再活动时,可能希望将其恢复到初始值,通过设置全局的恢复策略可以使状态机进入一个状态而不用明确制定属性的值。 QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);当设置了恢复策略以后,状态机将自动恢复所有…

sklearn中多分类和多标签分类评估方法总结

一、任务区分 多分类分类任务&#xff1a;在多分类任务中&#xff0c;每个样本只能被分配到一个类别中。换句话说&#xff0c;每个样本只有一个正确的标签。例如&#xff0c;将图像分为不同的物体类别&#xff0c;如猫、狗、汽车等。 多标签分类任务&#xff1a;在多标签分类任…

助力数字农林业发展服务香榧智慧种植,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建香榧种植场景下香榧果实检测识别系统

作为一个生在北方但在南方居住多年的人&#xff0c;居然头一次听过香榧&#xff08;fei&#xff09;这种作物&#xff0c;而且这个字还不会念&#xff0c;查了以后才知道读音&#xff08;fei&#xff09;&#xff0c;三声&#xff0c;这着实引起了我的好奇心&#xff0c;我相信…

STM32使用ADC单/多通道检测数据

文章目录 1. STM32单片机ADC功能详解 2. AD单通道 2.1 初始化 2.2 ADC.c 2.3 ADC.h 2.4 main.c 3. AD多通道 3.1 ADC.c 3.2 ADC.h 3.3 main.c 3.4 完整工程文件 1. STM32单片机ADC功能详解 STM32单片机ADC功能详解 2. AD单通道 这个代码实现通过ADC功能采集三脚电…

【Vue2】关于response返回数据的错误小记

关于Vue2中response返回数据的一个错误小记 如图&#xff0c;在这里返回的时候&#xff0c;后端是通过List< String >返回的&#xff0c;response接收到的实际上是一个Array数组&#xff0c;但是赋值给searchedTaskList的时候&#xff0c;需要在.then包括的范围里面赋值给…

【SpringBoot】 什么是springboot(二)?springboot操作mybatisPlus、swagger、thymeleaf模板

文章目录 SpringBoot第三章1、整合mybatsPlus1-234-67-10问题 2、整合pageHelper分页3、MP代码生成器1、编写yml文件2、导入依赖3、创建mp代码生成器4、生成代码5、编写配置类扫描mapper类6、编写控制器类 4、swagger1、什么是swagger2、作用3、发展历程4、一个简单的swagger项…

ElastiCache Serverless for Redis应用场景和性能成本分析

一. 前言 传统基于实例节点的 Redis 缓存架构中&#xff0c;扩展性是一个重要影响因素。在很多场景中&#xff0c;例如广告投放、电商交易、游戏对战&#xff0c;流量是经常变化的。无论是主从还是集群模式&#xff0c;当大流量进入时&#xff0c;Redis 处理能力达到上限&…

“打工搬砖记”中吃什么的轮盘功能实现(二)

文章目录 打工搬砖记转盘主要的逻辑实现转盘的素材小结 打工搬砖记 先来一个吃什么轮盘的预览图&#xff0c;这轮盘文案加字呈圆形铺出来&#xff0c;开始后旋转到指定的选项处停下来。 已上线小程序“打工人搬砖记”&#xff0c;可以扫码进行预览观看。 转盘主要的逻辑实现…