<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/83706/random-high-byte-when-double-converted-to-signed-16-int-and-sent-over-ble</link><description>I am taking over a firmware Bluetooth project and am reading the code that is having some issues. Below is a snippet from a BLE characteristic read callback. Here a double is being converted to a 16 bit int. I am not sure why it is converted to a long</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 20 Jan 2022 12:41:08 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/83706/random-high-byte-when-double-converted-to-signed-16-int-and-sent-over-ble" /><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348697?ContentTypeID=1</link><pubDate>Thu, 20 Jan 2022 12:41:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e8dd32a7-9bd1-4bd9-8403-4f628c00ea88</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Can you share the value of read_force before and after you cast it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348605?ContentTypeID=1</link><pubDate>Thu, 20 Jan 2022 01:08:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b381f9a7-b208-42f2-bdd3-5d138a120eb3</guid><dc:creator>yayembedded</dc:creator><description>&lt;p&gt;read_force() returns a double.&amp;nbsp; So I would have to at least cast it to an int16_t&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348386?ContentTypeID=1</link><pubDate>Tue, 18 Jan 2022 21:44:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:670b2aff-4a70-47a7-b29f-3722361ae863</guid><dc:creator>smackenzie</dc:creator><description>&lt;p&gt;Try this&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;static ssize_t read_force_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) {
	int16_t force = read_force();
	printk(&amp;quot;read_force callback. Value: %i\n&amp;quot;, force);
	return bt_gatt_attr_read(conn, attr, buf, len, offset, &amp;amp;force, sizeof(force));
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348385?ContentTypeID=1</link><pubDate>Tue, 18 Jan 2022 21:19:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5be2ac96-76a5-497c-9d4a-281a218f7d99</guid><dc:creator>yayembedded</dc:creator><description>&lt;p&gt;Hi thanks for helping.&amp;nbsp; This is the read characteristic callback function for BLE.&amp;nbsp; How would you recommend converting a double to an int16?&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;//read force characteristic
static ssize_t read_force_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
    void *buf, uint16_t len, uint16_t offset) {
  double force = read_force();
  long val_long = (long) force;
  int16_t val16 = (int16_t) val_long;

  int16_t *val16_ptr = &amp;amp;val16;
  
  printk(&amp;quot;read_force callback %d\n&amp;quot;, *val16_ptr);
  return bt_gatt_attr_read(conn, attr, buf, len, offset, val16_ptr,
      sizeof(*val16_ptr));
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348383?ContentTypeID=1</link><pubDate>Tue, 18 Jan 2022 20:52:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:21deba15-9491-4908-af91-039cdefa7697</guid><dc:creator>smackenzie</dc:creator><description>&lt;p&gt;Some more context would be helpful. Can you show the rest of the function?&lt;/p&gt;
&lt;p&gt;`&lt;span&gt;val16` seems to be the value you are reading, but you are not returning it from the function.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;What variable are you looking at that contains the bad value?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If your function looks like this&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static int read_value() {
	double force = read_force();

	long val_long = (long) force;
	int16_t val16 = (int16_t) val_long;
	int16_t *val16_ptr = &amp;amp;val16;

	return bt_gatt_attr_read(conn,
		attr,
		buf,
		len,
		offset,
		val16_ptr,
		sizeof(*val16_ptr));

}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then the value read from the attribute is `val16` and only stored in a local value, so that value will never be usable outside this function.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Also im not understanding why `val16` is being assigned to anything if its value is gong to be overwritten with the attribute&amp;#39;s&amp;nbsp;value.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/348155?ContentTypeID=1</link><pubDate>Tue, 18 Jan 2022 02:53:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:87703e14-601c-4850-aff7-636f3a3be597</guid><dc:creator>yayembedded</dc:creator><description>&lt;p&gt;Hi.&amp;nbsp; I don&amp;#39;t understand this scenario: &amp;quot;&lt;span&gt;If you are casting a `double*` to a `*int16_t*` and tying to dereference, you are going to get undefined behavior because its going to read 8 bytes from something that only has 2 bytes, so the value could be anything.&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;My code is pasted in the original post.&amp;nbsp; I don&amp;#39;t&amp;nbsp;dereference a pointer at any time.&amp;nbsp;&amp;nbsp;bt_gatt_attr_read takes in a pointer and the number of bytes (2).&amp;nbsp; It&amp;#39;s not reading more than 2 bytes, but the high byte that is read is seemingly random.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Random high byte when double converted to signed 16 int and sent over BLE</title><link>https://devzone.nordicsemi.com/thread/347888?ContentTypeID=1</link><pubDate>Sun, 16 Jan 2022 21:55:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:30d8b582-7159-436b-9f95-7423c9b57ba3</guid><dc:creator>smackenzie</dc:creator><description>&lt;p&gt;A double is 8 bytes and a&amp;nbsp;int16_t is 2 bytes.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you cast a double to a&amp;nbsp;&lt;span&gt;int16_t&amp;nbsp;you are going to truncate the decimal value.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;double d = 250.55;
int16_t i = (int16_t)d; //i = 250&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you are casting a `double*` to a `*int16_t*` and tying to dereference, you are going to get undefined behavior because its going to read 8 bytes from something that only has 2 bytes, so the value could be anything. You are probably&amp;nbsp;doing something similar to this if your value changes on different&amp;nbsp;runs of the application.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;int16_t i = 250;
double d = *(double*)&amp;amp;i; // Undefine behavior. The value of i could be anything&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you go the other way and cast a&amp;nbsp;`*int16_t*` to a&amp;nbsp;double*`&amp;nbsp;and&amp;nbsp;&lt;/span&gt;dereference, you will get a seemingly &lt;span&gt;nonsensical value but it should stay the same between runs. This is because the memory layout of int_16 and double are not the same and you are reading only 2 bytes of the double.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;double d = 250.55;
int16_t i = *(int16_t*)&amp;amp;d;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>