Support /proc/uptime
This commit is contained in:
parent
9f01df47ea
commit
46b77e2544
@ -6225,4 +6225,5 @@
|
|||||||
(2013-12-13).
|
(2013-12-13).
|
||||||
* fs/procfs/procfs_utils.c: Move some re-usable functions out of
|
* fs/procfs/procfs_utils.c: Move some re-usable functions out of
|
||||||
fs_procfsproc.c into a utility file (2013-12-14).
|
fs_procfsproc.c into a utility file (2013-12-14).
|
||||||
|
* fs/procfs/fs_procfsuptime.c: Supports /proc/uptime (2013-12-14).
|
||||||
|
|
||||||
|
@ -35,6 +35,10 @@ config FS_PROCFS_EXCLUDE_PROCESS
|
|||||||
This will reduce code space, but then giving access to process info
|
This will reduce code space, but then giving access to process info
|
||||||
was kinda the whole point of procfs, but hey, whatever.
|
was kinda the whole point of procfs, but hey, whatever.
|
||||||
|
|
||||||
|
config FS_PROCFS_EXCLUDE_UPTIME
|
||||||
|
bool "Exclude uptime"
|
||||||
|
default n
|
||||||
|
|
||||||
config FS_PROCFS_EXCLUDE_PARTITIONS
|
config FS_PROCFS_EXCLUDE_PARTITIONS
|
||||||
bool "Exclude partitions"
|
bool "Exclude partitions"
|
||||||
depends on MTD_PARTITION
|
depends on MTD_PARTITION
|
||||||
|
@ -37,7 +37,7 @@ ifeq ($(CONFIG_FS_PROCFS),y)
|
|||||||
# Files required for procfs file system support
|
# Files required for procfs file system support
|
||||||
|
|
||||||
ASRCS +=
|
ASRCS +=
|
||||||
CSRCS += fs_procfs.c fs_procfsproc.c fs_procfsutil.c
|
CSRCS += fs_procfs.c fs_procfsutil.c fs_procfsproc.c fs_procfsuptime.c
|
||||||
|
|
||||||
# Include procfs build support
|
# Include procfs build support
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
extern const struct procfs_operations process_operations;
|
extern const struct procfs_operations process_operations;
|
||||||
|
extern const struct procfs_operations uptime_operations;
|
||||||
extern const struct procfs_operations mtd_procfsoperations;
|
extern const struct procfs_operations mtd_procfsoperations;
|
||||||
extern const struct procfs_operations part_procfsoperations;
|
extern const struct procfs_operations part_procfsoperations;
|
||||||
extern const struct procfs_operations smartfs_procfsoperations;
|
extern const struct procfs_operations smartfs_procfsoperations;
|
||||||
@ -101,6 +102,9 @@ static const struct procfs_entry_s g_procfsentries[] =
|
|||||||
#if defined(CONFIG_MTD_PARTITION) && !defined(CONFIG_FS_PROCFS_EXCLUDE_PARTITON)
|
#if defined(CONFIG_MTD_PARTITION) && !defined(CONFIG_FS_PROCFS_EXCLUDE_PARTITON)
|
||||||
{ "partitions", &part_procfsoperations },
|
{ "partitions", &part_procfsoperations },
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(CONFIG_FS_PROCFS_EXCLUDE_UPTIME)
|
||||||
|
{ "uptime", &uptime_operations },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t g_procfsentrycount = sizeof(g_procfsentries) /
|
static const uint8_t g_procfsentrycount = sizeof(g_procfsentries) /
|
||||||
|
@ -68,6 +68,9 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
/* Determines the size of an intermeidate buffer that must be large enough
|
||||||
|
* to handle the longest line generated by this logic.
|
||||||
|
*/
|
||||||
|
|
||||||
#define STATUS_LINELEN 32
|
#define STATUS_LINELEN 32
|
||||||
|
|
||||||
@ -344,7 +347,7 @@ static ssize_t process_status(FAR struct process_file_s *attr,
|
|||||||
return totalsize;
|
return totalsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show the signal mast */
|
/* Show the signal mask */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
linesize = snprintf(attr->line, STATUS_LINELEN, "%-12s%08x\n", "SigMask:",
|
linesize = snprintf(attr->line, STATUS_LINELEN, "%-12s%08x\n", "SigMask:",
|
||||||
|
359
fs/procfs/fs_procfsuptime.c
Normal file
359
fs/procfs/fs_procfsuptime.c
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* fs/procfs/fs_procfsuptime.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/clock.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/fs/procfs.h>
|
||||||
|
|
||||||
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS)
|
||||||
|
#ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
/* Determines the size of an intermeidate buffer that must be large enough
|
||||||
|
* to handle the longest line generated by this logic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UPTIME_LINELEN 16
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* This structure describes one open "file" */
|
||||||
|
|
||||||
|
struct uptime_file_s
|
||||||
|
{
|
||||||
|
struct procfs_file_s base; /* Base open file structure */
|
||||||
|
char line[UPTIME_LINELEN]; /* Pre-allocated buffer for formatted lines */
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* File system methods */
|
||||||
|
|
||||||
|
static int uptime_open(FAR struct file *filep, FAR const char *relpath,
|
||||||
|
int oflags, mode_t mode);
|
||||||
|
static int uptime_close(FAR struct file *filep);
|
||||||
|
static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
|
||||||
|
size_t buflen);
|
||||||
|
|
||||||
|
static int uptime_dup(FAR const struct file *oldp,
|
||||||
|
FAR struct file *newp);
|
||||||
|
|
||||||
|
static int uptime_stat(FAR const char *relpath, FAR struct stat *buf);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Variables
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Variables
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* See fs_mount.c -- this structure is explicitly externed there.
|
||||||
|
* We use the old-fashioned kind of initializers so that this will compile
|
||||||
|
* with any compiler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const struct procfs_operations uptime_operations =
|
||||||
|
{
|
||||||
|
uptime_open, /* open */
|
||||||
|
uptime_close, /* close */
|
||||||
|
uptime_read, /* read */
|
||||||
|
NULL, /* write */
|
||||||
|
|
||||||
|
uptime_dup, /* dup */
|
||||||
|
|
||||||
|
NULL, /* opendir */
|
||||||
|
NULL, /* closedir */
|
||||||
|
NULL, /* readdir */
|
||||||
|
NULL, /* rewinddir */
|
||||||
|
|
||||||
|
uptime_stat /* stat */
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uptime_open
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int uptime_open(FAR struct file *filep, FAR const char *relpath,
|
||||||
|
int oflags, mode_t mode)
|
||||||
|
{
|
||||||
|
FAR struct uptime_file_s *attr;
|
||||||
|
|
||||||
|
fvdbg("Open '%s'\n", relpath);
|
||||||
|
|
||||||
|
/* PROCFS is read-only. Any attempt to open with any kind of write
|
||||||
|
* access is not permitted.
|
||||||
|
*
|
||||||
|
* REVISIT: Write-able proc files could be quite useful.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: Only O_RDONLY supported\n");
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "uptime" is the only acceptable value for the relpath */
|
||||||
|
|
||||||
|
if (strcmp(relpath, "uptime") != 0)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: relpath is '%s'\n", relpath);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a container to hold the file attributes */
|
||||||
|
|
||||||
|
attr = (FAR struct uptime_file_s *)kzalloc(sizeof(struct uptime_file_s));
|
||||||
|
if (!attr)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: Failed to allocate file attributes\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the attributes as the open-specific state in filep->f_priv */
|
||||||
|
|
||||||
|
filep->f_priv = (FAR void *)attr;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uptime_close
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int uptime_close(FAR struct file *filep)
|
||||||
|
{
|
||||||
|
FAR struct uptime_file_s *attr;
|
||||||
|
|
||||||
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
|
attr = (FAR struct uptime_file_s *)filep->f_priv;
|
||||||
|
DEBUGASSERT(attr);
|
||||||
|
|
||||||
|
/* Release the file attributes structure */
|
||||||
|
|
||||||
|
kfree(attr);
|
||||||
|
filep->f_priv = NULL;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uptime_read
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
|
||||||
|
size_t buflen)
|
||||||
|
{
|
||||||
|
FAR struct uptime_file_s *attr;
|
||||||
|
size_t linesize;
|
||||||
|
off_t offset;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSTEM_TIME64
|
||||||
|
/* 32-bit timer */
|
||||||
|
|
||||||
|
uint64_t upticks = clock_systimer64();
|
||||||
|
|
||||||
|
#if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT)
|
||||||
|
double now = (double)upticks / (double)CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
#else
|
||||||
|
uint64_t sec = upticks / CLOCKS_PER_SEC;
|
||||||
|
unsigned int remainder = (unsigned int)(upticks % CLOCKS_PER_SEC);
|
||||||
|
unsigned int csec = (100 * remainder + (CLOCKS_PER_SEC / 2)) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* 32-bit timer */
|
||||||
|
|
||||||
|
uint32_t upticks = clock_systimer();
|
||||||
|
|
||||||
|
#if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT)
|
||||||
|
double now = (double)upticks / (double)CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
#else
|
||||||
|
uint32_t sec = upticks / CLOCKS_PER_SEC;
|
||||||
|
unsigned int remainder = (unsigned int)(upticks % CLOCKS_PER_SEC);
|
||||||
|
unsigned int csec = (100 * remainder + (CLOCKS_PER_SEC / 2)) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen);
|
||||||
|
|
||||||
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
|
attr = (FAR struct uptime_file_s *)filep->f_priv;
|
||||||
|
DEBUGASSERT(attr);
|
||||||
|
|
||||||
|
#if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT)
|
||||||
|
/* Convert the system up time to seconds + hundredths of seconds */
|
||||||
|
|
||||||
|
linesize = snprintf(attr->line, UPTIME_LINELEN, "%10.2f\n", now);
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Make sure that rounding did not force the hundredths of a second above 99 */
|
||||||
|
|
||||||
|
if (csec > 99)
|
||||||
|
{
|
||||||
|
sec++;
|
||||||
|
csec -= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the system up time to seconds + hundredths of seconds */
|
||||||
|
|
||||||
|
linesize = snprintf(attr->line, UPTIME_LINELEN, "%7lu.%02u\n", sec, csec);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Transfer the system up time to user receive buffer */
|
||||||
|
|
||||||
|
offset = filep->f_pos;
|
||||||
|
ret = procfs_memcpy(attr->line, linesize, buffer, buflen, &offset);
|
||||||
|
|
||||||
|
/* Update the file offset */
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
filep->f_pos += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uptime_dup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Duplicate open file data in the new file structure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int uptime_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||||
|
{
|
||||||
|
FAR struct uptime_file_s *oldattr;
|
||||||
|
FAR struct uptime_file_s *newattr;
|
||||||
|
|
||||||
|
fvdbg("Dup %p->%p\n", oldp, newp);
|
||||||
|
|
||||||
|
/* Recover our private data from the old struct file instance */
|
||||||
|
|
||||||
|
oldattr = (FAR struct uptime_file_s *)oldp->f_priv;
|
||||||
|
DEBUGASSERT(oldattr);
|
||||||
|
|
||||||
|
/* Allocate a new container to hold the task and attribute selection */
|
||||||
|
|
||||||
|
newattr = (FAR struct uptime_file_s *)kzalloc(sizeof(struct uptime_file_s));
|
||||||
|
if (!newattr)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: Failed to allocate file attributes\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The copy the file attribtes from the old attributes to the new */
|
||||||
|
|
||||||
|
memcpy(&newattr->base, &oldattr->base, sizeof(struct procfs_file_s));
|
||||||
|
|
||||||
|
/* Save the new attributes in the new file structure */
|
||||||
|
|
||||||
|
newp->f_priv = (FAR void *)newattr;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uptime_stat
|
||||||
|
*
|
||||||
|
* Description: Return information about a file or directory
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int uptime_stat(const char *relpath, struct stat *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* "uptime" is the only acceptable value for the relpath */
|
||||||
|
|
||||||
|
if (strcmp(relpath, "uptime") != 0)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: relpath is '%s'\n", relpath);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "uptime" is the name for a read-only file */
|
||||||
|
|
||||||
|
buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR;
|
||||||
|
buf->st_size = 0;
|
||||||
|
buf->st_blksize = 0;
|
||||||
|
buf->st_blocks = 0;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#endif /* CONFIG_FS_PROCFS_EXCLUDE_PROCESS */
|
||||||
|
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */
|
@ -147,6 +147,7 @@ static Bigint *Balloc(int k)
|
|||||||
rv->k = k;
|
rv->k = k;
|
||||||
rv->maxwds = x;
|
rv->maxwds = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv->sign = rv->wds = 0;
|
rv->sign = rv->wds = 0;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -189,6 +190,7 @@ static Bigint *multadd(Bigint * b, int m, int a)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
while (++i < wds);
|
while (++i < wds);
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
if (wds >= b->maxwds)
|
if (wds >= b->maxwds)
|
||||||
@ -201,6 +203,7 @@ static Bigint *multadd(Bigint * b, int m, int a)
|
|||||||
b->x[wds++] = a;
|
b->x[wds++] = a;
|
||||||
b->wds = wds;
|
b->wds = wds;
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +243,7 @@ static int hi0bits(unsigned long x)
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,11 +258,13 @@ static int lo0bits(unsigned long *y)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x & 2)
|
if (x & 2)
|
||||||
{
|
{
|
||||||
*y = x >> 1;
|
*y = x >> 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*y = x >> 2;
|
*y = x >> 2;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -297,6 +303,7 @@ static int lo0bits(unsigned long *y)
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*y = x;
|
*y = x;
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
@ -336,11 +343,13 @@ static Bigint *mult(Bigint * a, Bigint * b)
|
|||||||
{
|
{
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = Balloc(k);
|
c = Balloc(k);
|
||||||
for (x = c->x, xa = x + wc; x < xa; x++)
|
for (x = c->x, xa = x + wc; x < xa; x++)
|
||||||
{
|
{
|
||||||
*x = 0;
|
*x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xa = a->x;
|
xa = a->x;
|
||||||
xae = xa + wa;
|
xae = xa + wa;
|
||||||
xb = b->x;
|
xb = b->x;
|
||||||
@ -363,8 +372,10 @@ static Bigint *mult(Bigint * a, Bigint * b)
|
|||||||
Storeinc(xc, z2, z);
|
Storeinc(xc, z2, z);
|
||||||
}
|
}
|
||||||
while (x < xae);
|
while (x < xae);
|
||||||
|
|
||||||
*xc = carry;
|
*xc = carry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((y = *xb >> 16))
|
if ((y = *xb >> 16))
|
||||||
{
|
{
|
||||||
x = xa;
|
x = xa;
|
||||||
@ -380,6 +391,7 @@ static Bigint *mult(Bigint * a, Bigint * b)
|
|||||||
carry = z2 >> 16;
|
carry = z2 >> 16;
|
||||||
}
|
}
|
||||||
while (x < xae);
|
while (x < xae);
|
||||||
|
|
||||||
*xc = z2;
|
*xc = z2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,10 +410,12 @@ static Bigint *mult(Bigint * a, Bigint * b)
|
|||||||
*xc++ = z & 0xffff;
|
*xc++ = z & 0xffff;
|
||||||
}
|
}
|
||||||
while (x < xae);
|
while (x < xae);
|
||||||
|
|
||||||
*xc = carry;
|
*xc = carry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
|
for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
|
||||||
c->wds = wc;
|
c->wds = wc;
|
||||||
return c;
|
return c;
|
||||||
@ -438,6 +452,7 @@ static Bigint *pow5mult(Bigint * b, int k)
|
|||||||
Bfree(b);
|
Bfree(b);
|
||||||
b = b1;
|
b = b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(k >>= 1))
|
if (!(k >>= 1))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -448,8 +463,10 @@ static Bigint *pow5mult(Bigint * b, int k)
|
|||||||
p51 = p5->next = mult(p5, p5);
|
p51 = p5->next = mult(p5, p5);
|
||||||
p51->next = 0;
|
p51->next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p5 = p51;
|
p5 = p51;
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,12 +487,14 @@ static Bigint *lshift(Bigint * b, int k)
|
|||||||
{
|
{
|
||||||
k1++;
|
k1++;
|
||||||
}
|
}
|
||||||
|
|
||||||
b1 = Balloc(k1);
|
b1 = Balloc(k1);
|
||||||
x1 = b1->x;
|
x1 = b1->x;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
*x1++ = 0;
|
*x1++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = b->x;
|
x = b->x;
|
||||||
xe = x + b->wds;
|
xe = x + b->wds;
|
||||||
#ifdef Pack_32
|
#ifdef Pack_32
|
||||||
@ -489,6 +508,7 @@ static Bigint *lshift(Bigint * b, int k)
|
|||||||
z = *x++ >> k1;
|
z = *x++ >> k1;
|
||||||
}
|
}
|
||||||
while (x < xe);
|
while (x < xe);
|
||||||
|
|
||||||
if ((*x1 = z))
|
if ((*x1 = z))
|
||||||
{
|
{
|
||||||
++n1;
|
++n1;
|
||||||
@ -505,6 +525,7 @@ static Bigint *lshift(Bigint * b, int k)
|
|||||||
z = *x++ >> k1;
|
z = *x++ >> k1;
|
||||||
}
|
}
|
||||||
while (x < xe);
|
while (x < xe);
|
||||||
|
|
||||||
if ((*x1 = z))
|
if ((*x1 = z))
|
||||||
{
|
{
|
||||||
++n1;
|
++n1;
|
||||||
@ -512,11 +533,14 @@ static Bigint *lshift(Bigint * b, int k)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
do
|
{
|
||||||
{
|
do
|
||||||
*x1++ = *x++;
|
{
|
||||||
}
|
*x1++ = *x++;
|
||||||
while (x < xe);
|
}
|
||||||
|
while (x < xe);
|
||||||
|
}
|
||||||
|
|
||||||
b1->wds = n1 - 1;
|
b1->wds = n1 - 1;
|
||||||
Bfree(b);
|
Bfree(b);
|
||||||
return b1;
|
return b1;
|
||||||
@ -534,13 +558,18 @@ static int cmp(Bigint * a, Bigint * b)
|
|||||||
{
|
{
|
||||||
ldbg("cmp called with a->x[a->wds-1] == 0\n");
|
ldbg("cmp called with a->x[a->wds-1] == 0\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j > 1 && !b->x[j - 1])
|
if (j > 1 && !b->x[j - 1])
|
||||||
{
|
{
|
||||||
ldbg("cmp called with b->x[b->wds-1] == 0\n");
|
ldbg("cmp called with b->x[b->wds-1] == 0\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (i -= j)
|
if (i -= j)
|
||||||
return i;
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
xa0 = a->x;
|
xa0 = a->x;
|
||||||
xa = xa0 + j;
|
xa = xa0 + j;
|
||||||
xb0 = b->x;
|
xb0 = b->x;
|
||||||
@ -548,9 +577,14 @@ static int cmp(Bigint * a, Bigint * b)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (*--xa != *--xb)
|
if (*--xa != *--xb)
|
||||||
return *xa < *xb ? -1 : 1;
|
{
|
||||||
|
return *xa < *xb ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (xa <= xa0)
|
if (xa <= xa0)
|
||||||
break;
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -573,6 +607,7 @@ static Bigint *diff(Bigint * a, Bigint * b)
|
|||||||
c->x[0] = 0;
|
c->x[0] = 0;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
{
|
{
|
||||||
c = a;
|
c = a;
|
||||||
@ -581,7 +616,10 @@ static Bigint *diff(Bigint * a, Bigint * b)
|
|||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i = 0;
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
c = Balloc(a->k);
|
c = Balloc(a->k);
|
||||||
c->sign = i;
|
c->sign = i;
|
||||||
wa = a->wds;
|
wa = a->wds;
|
||||||
@ -604,6 +642,7 @@ static Bigint *diff(Bigint * a, Bigint * b)
|
|||||||
Storeinc(xc, z, y);
|
Storeinc(xc, z, y);
|
||||||
}
|
}
|
||||||
while (xb < xbe);
|
while (xb < xbe);
|
||||||
|
|
||||||
while (xa < xae)
|
while (xa < xae)
|
||||||
{
|
{
|
||||||
y = (*xa & 0xffff) + borrow;
|
y = (*xa & 0xffff) + borrow;
|
||||||
@ -623,6 +662,7 @@ static Bigint *diff(Bigint * a, Bigint * b)
|
|||||||
*xc++ = y & 0xffff;
|
*xc++ = y & 0xffff;
|
||||||
}
|
}
|
||||||
while (xb < xbe);
|
while (xb < xbe);
|
||||||
|
|
||||||
while (xa < xae)
|
while (xa < xae)
|
||||||
{
|
{
|
||||||
y = *xa++ + borrow;
|
y = *xa++ + borrow;
|
||||||
@ -631,8 +671,12 @@ static Bigint *diff(Bigint * a, Bigint * b)
|
|||||||
*xc++ = y & 0xffff;
|
*xc++ = y & 0xffff;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (!*--xc)
|
while (!*--xc)
|
||||||
wa--;
|
{
|
||||||
|
wa--;
|
||||||
|
}
|
||||||
|
|
||||||
c->wds = wa;
|
c->wds = wa;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -663,7 +707,10 @@ static Bigint *d2b(double d, int *e, int *bits)
|
|||||||
z >>= k;
|
z >>= k;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
x[0] = y;
|
{
|
||||||
|
x[0] = y;
|
||||||
|
}
|
||||||
|
|
||||||
i = b->wds = (x[1] = z) ? 2 : 1;
|
i = b->wds = (x[1] = z) ? 2 : 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -727,6 +774,7 @@ static Bigint *d2b(double d, int *e, int *bits)
|
|||||||
x[1] = z >> 16;
|
x[1] = z >> 16;
|
||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
k += 32;
|
k += 32;
|
||||||
}
|
}
|
||||||
while (!x[i])
|
while (!x[i])
|
||||||
@ -747,10 +795,12 @@ static Bigint *d2b(double d, int *e, int *bits)
|
|||||||
*bits = (i + 2) * 16 - hi0bits(x[i]);
|
*bits = (i + 2) * 16 - hi0bits(x[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const double tens[] = {
|
static const double tens[] =
|
||||||
|
{
|
||||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||||
1e20, 1e21, 1e22
|
1e20, 1e21, 1e22
|
||||||
@ -790,6 +840,7 @@ static int quorem(Bigint * b, Bigint * S)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sx = S->x;
|
sx = S->x;
|
||||||
sxe = sx + --n;
|
sxe = sx + --n;
|
||||||
bx = b->x;
|
bx = b->x;
|
||||||
@ -801,6 +852,7 @@ static int quorem(Bigint * b, Bigint * S)
|
|||||||
ldbg("oversized quotient in quorem\n");
|
ldbg("oversized quotient in quorem\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
borrow = 0;
|
borrow = 0;
|
||||||
@ -829,11 +881,15 @@ static int quorem(Bigint * b, Bigint * S)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
while (sx <= sxe);
|
while (sx <= sxe);
|
||||||
|
|
||||||
if (!*bxe)
|
if (!*bxe)
|
||||||
{
|
{
|
||||||
bx = b->x;
|
bx = b->x;
|
||||||
while (--bxe > bx && !*bxe)
|
while (--bxe > bx && !*bxe)
|
||||||
--n;
|
{
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
|
||||||
b->wds = n;
|
b->wds = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -877,6 +933,7 @@ static int quorem(Bigint * b, Bigint * S)
|
|||||||
b->wds = n;
|
b->wds = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,14 +978,14 @@ static int quorem(Bigint * b, Bigint * S)
|
|||||||
char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
||||||
{
|
{
|
||||||
/* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt;
|
/* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt;
|
||||||
* trailing zeros are suppressed from the returned string. If not null, *rve
|
* trailing zeros are suppressed from the returned string. If not null, *rve
|
||||||
* is set to point to the end of the return value. If d is +-Infinity or
|
* is set to point to the end of the return value. If d is +-Infinity or
|
||||||
* NaN, then *decpt is set to 9999.
|
* NaN, then *decpt is set to 9999.
|
||||||
*
|
*
|
||||||
* mode: 0 ==> shortest string that yields d when read in and rounded to
|
* mode: 0 ==> shortest string that yields d when read in and rounded to
|
||||||
* nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with
|
* nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with
|
||||||
* IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives
|
* IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives
|
||||||
* 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives
|
* 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives
|
||||||
* a return value similar to that of ecvt, except that trailing zeros are
|
* a return value similar to that of ecvt, except that trailing zeros are
|
||||||
* suppressed. 3 ==> through ndigits past the decimal point. This gives a
|
* suppressed. 3 ==> through ndigits past the decimal point. This gives a
|
||||||
* return value similar to that from fcvt, except that trailing zeros are
|
* return value similar to that from fcvt, except that trailing zeros are
|
||||||
@ -938,9 +995,9 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
* sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit
|
* sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit
|
||||||
* generation. 6-9 ==> don't try fast floating-point estimate (if
|
* generation. 6-9 ==> don't try fast floating-point estimate (if
|
||||||
* applicable).
|
* applicable).
|
||||||
*
|
*
|
||||||
* Values of mode other than 0-9 are treated as mode 0.
|
* Values of mode other than 0-9 are treated as mode 0.
|
||||||
*
|
*
|
||||||
* Sufficient space is allocated to the return value to hold the suppressed
|
* Sufficient space is allocated to the return value to hold the suppressed
|
||||||
* trailing zeros. */
|
* trailing zeros. */
|
||||||
|
|
||||||
@ -989,11 +1046,14 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
#endif
|
#endif
|
||||||
"NaN";
|
"NaN";
|
||||||
if (rve)
|
if (rve)
|
||||||
*rve =
|
{
|
||||||
|
*rve =
|
||||||
#ifdef IEEE_Arith
|
#ifdef IEEE_Arith
|
||||||
s[3] ? s + 8 :
|
s[3] ? s + 8 :
|
||||||
#endif
|
#endif
|
||||||
s + 3;
|
s + 3;
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1002,7 +1062,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
*decpt = 1;
|
*decpt = 1;
|
||||||
s = "0";
|
s = "0";
|
||||||
if (rve)
|
if (rve)
|
||||||
*rve = s + 1;
|
{
|
||||||
|
*rve = s + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,10 +1080,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
* log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) log10(d) =
|
* log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) log10(d) =
|
||||||
* (i-Bias)*log(2)/log(10) + log10(d2) This suggests computing an
|
* (i-Bias)*log(2)/log(10) + log10(d2) This suggests computing an
|
||||||
* approximation k to log10(d) by k = (i - Bias)*0.301029995663981 + (
|
* approximation k to log10(d) by k = (i - Bias)*0.301029995663981 + (
|
||||||
* (d2-1.5)*0.289529654602168 + 0.176091259055681 ); We want k to be too
|
* (d2-1.5)*0.289529654602168 + 0.176091259055681 ); We want k to be too
|
||||||
* large rather than too small. The error in the first-order Taylor
|
* large rather than too small. The error in the first-order Taylor
|
||||||
* series approximation is in our favor, so we just round up the constant
|
* series approximation is in our favor, so we just round up the constant
|
||||||
* enough to compensate for any error in the multiplication of (i - Bias)
|
* enough to compensate for any error in the multiplication of (i - Bias)
|
||||||
* by 0.301029995663981; since |i - Bias| <= 1077, and 1077 * 0.30103 *
|
* by 0.301029995663981; since |i - Bias| <= 1077, and 1077 * 0.30103 *
|
||||||
* 2^-52 ~=~ 7.2e-14, adding 1e-13 to the constant term more than
|
* 2^-52 ~=~ 7.2e-14, adding 1e-13 to the constant term more than
|
||||||
* suffices. Hence we adjust the constant term to 0.1760912590558. (We
|
* suffices. Hence we adjust the constant term to 0.1760912590558. (We
|
||||||
@ -1049,6 +1112,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
{
|
{
|
||||||
k--; /* want k = floor(ds) */
|
k--; /* want k = floor(ds) */
|
||||||
}
|
}
|
||||||
|
|
||||||
k_check = 1;
|
k_check = 1;
|
||||||
|
|
||||||
if (k >= 0 && k <= Ten_pmax)
|
if (k >= 0 && k <= Ten_pmax)
|
||||||
@ -1226,11 +1290,20 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
d -= L;
|
d -= L;
|
||||||
*s++ = '0' + (int)L;
|
*s++ = '0' + (int)L;
|
||||||
if (d < eps)
|
if (d < eps)
|
||||||
goto ret1;
|
{
|
||||||
|
goto ret1;
|
||||||
|
}
|
||||||
|
|
||||||
if (1. - d < eps)
|
if (1. - d < eps)
|
||||||
goto bump_up;
|
{
|
||||||
|
goto bump_up;
|
||||||
|
}
|
||||||
|
|
||||||
if (++i >= ilim)
|
if (++i >= ilim)
|
||||||
break;
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
eps *= 10.;
|
eps *= 10.;
|
||||||
d *= 10.;
|
d *= 10.;
|
||||||
}
|
}
|
||||||
@ -1239,7 +1312,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
/* Generate ilim digits, then fix them up. */
|
/* Generate ilim digits, then fix them up. */
|
||||||
|
|
||||||
eps *= tens[ilim - 1];
|
eps *= tens[ilim - 1];
|
||||||
for (i = 1;; i++, d *= 10.)
|
for (i = 1;; i++, d *= 10.)
|
||||||
{
|
{
|
||||||
@ -1249,13 +1322,16 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
if (i == ilim)
|
if (i == ilim)
|
||||||
{
|
{
|
||||||
if (d > 0.5 + eps)
|
if (d > 0.5 + eps)
|
||||||
goto bump_up;
|
{
|
||||||
|
goto bump_up;
|
||||||
|
}
|
||||||
else if (d < 0.5 - eps)
|
else if (d < 0.5 - eps)
|
||||||
{
|
{
|
||||||
while (*--s == '0');
|
while (*--s == '0');
|
||||||
s++;
|
s++;
|
||||||
goto ret1;
|
goto ret1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1280,7 +1356,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
{
|
{
|
||||||
S = mhi = 0;
|
S = mhi = 0;
|
||||||
if (ilim < 0 || d <= 5 * ds)
|
if (ilim < 0 || d <= 5 * ds)
|
||||||
goto no_digits;
|
{
|
||||||
|
goto no_digits;
|
||||||
|
}
|
||||||
|
|
||||||
goto one_digit;
|
goto one_digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,10 +1389,12 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
*s = '0';
|
*s = '0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
++*s++;
|
++*s++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(d *= 10.))
|
if (!(d *= 10.))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -1343,6 +1424,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
b5 += j;
|
b5 += j;
|
||||||
m5 = 0;
|
m5 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i = ilim) < 0)
|
if ((i = ilim) < 0)
|
||||||
{
|
{
|
||||||
m2 -= i;
|
m2 -= i;
|
||||||
@ -1374,8 +1456,11 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
Bfree(b);
|
Bfree(b);
|
||||||
b = b1;
|
b = b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((j = b5 - m5))
|
if ((j = b5 - m5))
|
||||||
b = pow5mult(b, j);
|
{
|
||||||
|
b = pow5mult(b, j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1471,10 +1556,12 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
if (ilim < 0 || cmp(b, S = multadd(S, 5, 0)) <= 0)
|
if (ilim < 0 || cmp(b, S = multadd(S, 5, 0)) <= 0)
|
||||||
{
|
{
|
||||||
/* no digits, fcvt style */
|
/* no digits, fcvt style */
|
||||||
|
|
||||||
no_digits:
|
no_digits:
|
||||||
k = -1 - ndigits;
|
k = -1 - ndigits;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
one_digit:
|
one_digit:
|
||||||
*s++ = '1';
|
*s++ = '1';
|
||||||
k++;
|
k++;
|
||||||
@ -1603,6 +1690,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|||||||
*s++ = '1';
|
*s++ = '1';
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
++*s++;
|
++*s++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1625,7 +1713,7 @@ ret:
|
|||||||
ret1:
|
ret1:
|
||||||
Bfree(b);
|
Bfree(b);
|
||||||
if (s == s0)
|
if (s == s0)
|
||||||
{ /* don't return empty string */
|
{ /* Don't return empty string */
|
||||||
*s++ = '0';
|
*s++ = '0';
|
||||||
k = 0;
|
k = 0;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
|||||||
|
|
||||||
/* Special handling for NaN and Infinity */
|
/* Special handling for NaN and Infinity */
|
||||||
|
|
||||||
if (isnan(value))
|
if (isnan(value))
|
||||||
{
|
{
|
||||||
lib_dtoa_string(obj, "NaN");
|
lib_dtoa_string(obj, "NaN");
|
||||||
return;
|
return;
|
||||||
@ -168,7 +168,7 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
|||||||
|
|
||||||
if (isinf(value))
|
if (isinf(value))
|
||||||
{
|
{
|
||||||
if (value < 0.0d)
|
if (value < 0.0)
|
||||||
{
|
{
|
||||||
obj->put(obj, '-');
|
obj->put(obj, '-');
|
||||||
}
|
}
|
||||||
@ -340,4 +340,3 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user