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

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

数字系统的由来

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

非位置化数字系统:罗马数字(经典代表),罗马数字共有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,一经查实,立即删除!

相关文章

Flutter 中的 ActionChip 小部件:全面指南

Flutter 中的 ActionChip 小部件&#xff1a;全面指南 在Flutter的Material组件库中&#xff0c;ActionChip是一种用于呈现一组相关操作的组件。它通常用于较少的、需要用户立即进行的操作&#xff0c;如过滤、排序或删除。ActionChip在视觉上与ChoiceChip相似&#xff0c;但使…

MyBatis的核心配置文件---configuration.xml

在MyBatis中&#xff0c;configuration.xml 是MyBatis的核心配置文件&#xff0c;它包含了MyBatis的全局配置信息&#xff0c;如数据源配置、事务管理器配置、别名配置、映射文件配置等。尽管在Spring Boot项目中&#xff0c;MyBatis的配置可以大部分通过属性配置在application…

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

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

Oracle JDK 与 OpenJDK:如何选择及其区别

引言 在选择 Java 开发工具包 (JDK) 时&#xff0c;很多开发者可能会困惑于 Oracle JDK 和 OpenJDK 之间的差异。本文将详细分析这两者的区别&#xff0c;帮助大家做出更明智的选择。 背景 2006 年&#xff0c;SUN 公司宣布 Java 开源&#xff0c;推出了 OpenJDK。2009 年&a…

(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…

Maven配置集profile

在开发场景中&#xff0c;通常有dev、sit和prod三个环境&#xff0c;分别对应开发、内部测试和生产。 在不同的环境中&#xff0c;因为数据、资源等隔离需要&#xff0c;往往需要不同的配置&#xff0c;这样在部署项目的时候就有着多套配置集灵活选择的需求&#xff08;避免手动…

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…

0514媒体处理面试题

编程&#xff1a;将给定字符串中的数字逆序&#xff0c;比如 abc2319bcj453 逆序后为 abc3549bcj132 思路&#xff1a; &#xff08;1&#xff09;双指针 &#xff08;2&#xff09;栈 #include "stdio.h" #include <iostream> #include <string> #in…

Golang RPC实现-day01

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

深入解析Java移位运算符

移位运算符是 Java 中常见的位操作符&#xff0c;主要包括左移&#xff08;<<&#xff09;、带符号右移&#xff08;>>&#xff09;和无符号右移&#xff08;>>>&#xff09;。这些运算符在性能优化、低级编程、数据压缩等领域广泛应用&#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;在多标签分类任…