当前位置: 首页 > news >正文

【Android】SharedPreferences存储中没有 Double 类型数据存储的解决方式

项目需求

存储定位数据,需要保存到小数点后10位数据。

需求分析

项目需求看起来很简单,其实实现起来也不难,我们直接使用SharedPreferences 存储一下就好了,反正也没其他要求。

好了,直接使用SharedPreferences 存储一下double数据就行了,
但是,SharedPreferences 不能存储double数据????

。。。。。。

是的,SharedPreferences 就是不能存储double类型的数据,虽然double类型的数据也是基本类型数据。。。

SharedPreferences中存储的数据是以key/value键值对的形式保存在XML文件中,这些数据具有一定的类型限制。具体来说,SharedPreferences能够直接存储的数据类型包括:

  • String:字符串类型,用于存储文本信息。
  • int:整型,用于存储整数数据。
  • float:浮点型,用于存储小数数据。
  • long:长整型,用于存储比int类型范围更大的整数数据。
  • boolean:布尔型,用于存储真或假两种状态。
  • StringSet:字符串集合类型,用于存储一组字符串。

那我们的需求是要保存的数据有10位小数的,但是使用float存储的话这个精度也打不到我们的需求,float 类型大约能精确表示 6-9 位有效数字,其中小数部分通常不超过 7 位;而 double 类型大约能精确表示 15-17 位有效数字,其中小数部分通常不超过 15 位。

所以我们要是满足需求的话是要使用double的,那怎么解决这个问题呢。

解决方法

解决方法一

将 double 转换为 String

// 存储 double
SharedPreferences sharedPreferences = context.getSharedPreferences("myPrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
double myDouble = 12.34;
editor.putString("myDoubleKey", String.valueOf(myDouble));
editor.apply();

使用的时候将一个 String 类型的带小数的数据转换为 double 类型,并保留10位小数。在这个过程中,可以使用 BigDecimal 来处理精度问题。

 public static double convertStringToDouble(String str) {try {// 将字符串转换为 BigDecimalBigDecimal bigDecimal = new BigDecimal(str);// 设置精度并进行舍入bigDecimal = bigDecimal.setScale(10, RoundingMode.HALF_UP);// 转换为 doublereturn bigDecimal.doubleValue();} catch (NumberFormatException e) {// 处理转换异常System.err.println("Invalid number format: " + str);return 0.0; // 或者根据需要返回其他值}}

解决方法二

将 double 值转换为 long

这看上去第一眼就懵逼了,不是,这个long能存小数吗?那肯定不能啊。

long 类型本身是整数,不能直接存储小数。但是,使用 long 来存储 double 值的关键在于如何处理它们的二进制表示。

首先我们要知道:

  • double 在内存中以 IEEE 754 格式表示,它包含了符号位、指数部分和尾数部分。

  • 这个表示可以被转换为一个 64 位的整数(long),通过 Double.doubleToRawLongBits() 方法。

  • 调用 Double.doubleToRawLongBits(value) 时,实际上是将 double 的内存表示(即二进制数)转换为一个 long 类型的数字。这并不是说 long 存储了小数,而是 long 存储了 double 的二进制表示。

  • 这个 long 数字可以被完整地还原为原始的 double 值。

浮点数的内存表示

double 类型在 Java 中使用 IEEE 754 标准进行表示。它包含:

  • 1 位符号位:表示正数或负数。
  • 11 位指数:用来表示数值的范围。
  • 52 位尾数(也称为有效数字):用于表示具体的数值。

这样,double 值的存储是通过这些位来表示其具体的数值特性。整个 double 在内存中占用 64 位(即 8 字节)。

使用 long 存储 double

由于 double 是 64 位的,而 long 也是 64 位的,可以利用这种大小的相同来存储 double 的原始位表示。具体流程如下:

存储过程
  • 转换:

当调用 Double.doubleToRawLongBits(value) 时,Java 将 double 值的 64 位二进制表示转换为一个 long 类型的数字。
这个 long 数字实际上是 double 值在内存中的“快照”,保留了所有的位信息。

  • 存储:

将得到的 long 数字存储到 SharedPreferences 中。

读取过程
  • 获取 long 值:

从 SharedPreferences 中读取之前存储的 long 值。

  • 还原:

使用 Double.longBitsToDouble(longBits) 方法将这个 long 值转换回原来的 double 值。

在这个过程中,Java 会重新解析这个 long 的位信息,将它解读为 double 的各个部分(符号位、指数、尾数),并计算出原始的浮点数值。


所以,假设我们有一个double数据3.14,使用SharedPreferences 存储这个数据时,我们要

转换 double 为 long

调用 Double.doubleToRawLongBits(value) 时,Java 会将 double 值的 64 位二进制表示转换为一个 long 类型的数字。这一过程包括以下几个步骤:

内部表示:

首先,Java 使用 IEEE 754 标准来表示 double 值。这个表示方式将 double 的数值分解为三部分:

  • 符号位(1 位):决定数值是正是负。
  • 指数部分(11 位):用于表示数值的范围和大小。
  • 尾数(有效数字)(52 位):表示实际的数值。

生成长整型:

Double.doubleToRawLongBits(value) 方法会将这些位拼接成一个 64 位的整数(long),这个整数就是 double 在内存中的原始二进制表示。

例如,对于 3.14,这个转换会生成一个特定的 long 值,表示 3.14 在 IEEE 754 中的位模式。

存储 long 到 SharedPreferences

得到了这个 long 值,就可以将其存储在 SharedPreferences 中:

long bits = Double.doubleToRawLongBits(value);
sharedPreferences.edit().putLong("key", bits).apply();

获取 long 值

需要读取存储的 double 值时,首先从 SharedPreferences 中获取之前存储的 long 值:

long bits = sharedPreferences.getLong("key", 0);

还原 long 为 double

将这个 long 值转换回原始的 double 值,使用 Double.longBitsToDouble(longBits) 方法:

double value = Double.longBitsToDouble(bits);

解析过程:
在这一过程中,Java 会根据 long 中的位信息重新构造出 double 的三个组成部分:

  • 符号位:如果符号位为 0,则表示正数;如果为 1,则表示负数。
  • 指数部分:根据存储的位值,Java 会计算出实际的指数。
  • 尾数:有效数字也会根据存储的位值重新构造出来。

这个过程会将 long 的二进制位解析成 double 需要的各个部分,然后合成最终的浮点数值。

通过以上的步骤,Java 能够有效地将 double 类型的数值以其原始二进制格式存储为 long 类型,从而在 SharedPreferences 中安全地保存和读取。这个方法不仅确保了数据的准确性,还利用了 long 和 double 相同的存储大小(64 位),使得转换过程既高效又简便。

相关文章:

【Android】SharedPreferences存储中没有 Double 类型数据存储的解决方式

项目需求 存储定位数据,需要保存到小数点后10位数据。 需求分析 项目需求看起来很简单,其实实现起来也不难,我们直接使用SharedPreferences 存储一下就好了,反正也没其他要求。 好了,直接使用SharedPreferences 存…...

ffmpeg:视频字幕嵌入(GPU加速)

实现方案 参考指令 ffmpeg -i input_video.mp4 -vf "subtitlessubtitles.srt" output_video.mp4 解决因文件名称复杂导致的指令执行失败问题(引号给文件框起来) ffmpeg -i "A.mp4" -vf "subtitlesB.srt" "c.mp4&qu…...

DCN网络进行新冠肺炎影像分类

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【BiLSTM模型实现电力数据预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现mnist手写数字识别】…...

C++中的继承——第二篇

一、继承与友元 友元关系不能够继承(就像父亲的朋友不一定是自己的朋友) 具体实现起来就是父类的友元可以访问父类的成员,但是不可以访问子类的成员 二、继承与静态成员 子类的静态成员变量本质上与父类的是同一份,存储在静态…...

动态规划探索篇

Leetcode63——不同路径Ⅱ 题目描述: 给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角(即 grid[0][0])。机器人尝试移动到 右下角(即 grid[m - 1][n - 1])。机器人每次只能向下或者向右移动一步。 网格…...

js中多let与var

在 JavaScript 中,let 和 var 都用于声明变量,但它们有一些关键的区别。主要区别包括作用域、变量提升、可重复声明、以及在全局作用域中的行为。 1. 作用域(Scope) let:块级作用域。用 let 声明的变量只在其所在的代…...

基于人工智能的搜索和推荐系统

互联网上的搜索历史分析和用户活动是个性化推荐的基础,这些推荐已成为电子商务行业和在线业务的强大营销工具。随着人工智能的使用,在线搜索也在改进,因为它会根据用户的视觉偏好提出建议,而不是根据每个客户的需求和偏好量身定制…...

冷钱包与热钱包的差异 | 加密货币存储的安全方案

随着加密货币的普及,越来越多的人开始重视加密资产的安全存储问题。钱包作为存储数字资产的工具,主要分为冷钱包和热钱包两大类。它们在安全性、便捷性以及适用场景方面各有优劣。了解这两者的差异,有助于投资者根据自己的需求选择合适的钱包…...

014:无人机遥控器操作

摘要:本文详细介绍了无人机遥控器及其相关操作。首先,解释了油门、升降舵、方向舵和副翼的概念、功能及操作方式,这些是控制无人机飞行姿态的关键部件。其次,介绍了美国手、日本手和中国手三种不同的操作模式,阐述了遥…...

PCL 点云高度归一化

目录 一、概述二、代码示例三、结果一、概述 点云高度归一化:为了消除地形起伏对点云数据高程值的影响,特别是在地物间存在显著高程差异的情况下,必须对点云数据进行归一化处理。这一步骤对于许多算法至关重要,因为它能够显著提升后续点云处理或分割任务的准确性。 归一化处…...

【Effective C++】阅读笔记4

1. 确保公有继承中有is-a的关系 Is-a关系理解 该关系就是派生类应该具备基类的所有特性,并且可以替代基类对象使用,例如猫和狗都是动物的派生类,因为猫和狗都和动物形成了is-a关系,猫和狗都是动物。 在该关系下,派生类…...

浅谈mysql【8.0】链接字符串

string connectionString "serveryour_server;useryour_user;passwordyour_password;databaseyour_database;sslmodenone;allowPublicKeyRetrievaltrue;Allow User VariablesTrue;";在 C# 中配置 MySQL 数据库连接字符串时,可以通过添加多个参数来控制连…...

BERT,RoBERTa,Ernie的理解

BERT: 全称:Bidirectional Encoder Representations from Transformers。可以理解为 “基于 Transformer 的双向编码器表示”。含义:是一种用于语言表征的预训练模型。它改变了以往传统单向语言模型预训练的方式,能够联合左侧和右…...

获取 Wind 数据并进行简单的择时分析

使用Python获取Wind数据并进行简单的择时分析时,需要按照以下步骤操作。 (1)登录Wind官网,在“金融解决方案”的下拉列表里选择“金融终端”选项,如下图3.2所示。 (2)根据自己计算机的实际情况…...

小檗碱的酵母代谢工程生物合成-文献精读78

De novo production of protoberberine and benzophenanthridine alkaloids through metabolic engineering of yeast 将酵母代谢工程应用于原小檗碱和苯并啡啶类生物碱的从头合成 苄基异喹啉类生物碱的微生物合成-文献精读77 香叶醇酵母生产机器学习优化酵母-文献精读66 黄…...

文件指针和写入操作

文件指针位置 w 模式: 打开文件时,文件指针位于文件的开头。如果文件已存在,文件内容会被清空。写入的数据会从文件开头开始覆盖原有内容。 a 模式: 打开文件时,文件指针位于文件的末尾。如果文件已存在,文…...

跨越科技与文化的桥梁——ROSCon China 2024 即将盛大开幕

在全球机器人技术飞速发展的浪潮中,ROS(Robot Operating System)作为一款开源的机器人操作系统,已成为无数开发者、研究人员和企业的首选工具。为了进一步推动ROS的应用与发展,全球知名的机器人操作系统会议——ROSCon…...

springboot+shiro 权限管理

一、为什么要了解权限框架 权限管理框架属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则用户可以访问而且只能访问自己被授权的资源。 目前常见的权限框架有Shiro和Spring Security,本篇文章记录springboot整合sh…...

PureMVC在Unity中的使用(含下载链接)

前言 Pure MVC是在基于模型、视图和控制器MVC模式建立的一个轻量级的应用框架,这种开源框架是免费的,它最初是执行的ActionScript 3语言使用的Adobe Flex、Flash和AIR,已经移植到几乎所有主要的发展平台,支持两个版本框架&#xf…...

25国考照片处理器使用流程图解❗

1、打开“国家公务员局”网站,进入2025公务员专题,找到考生考务入口 2、点击下载地址 3、这几个下载链接都可以 4、下载压缩包 5、解压后先看“使用说明”,再找到“照片处理工具”双击。 6、双击后会进入这样的界面,点击&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...